From: Toni Wilen Date: Tue, 7 Sep 2021 16:14:33 +0000 (+0300) Subject: Custom chipset WIP updates. X-Git-Tag: 4900~77 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=de37a956de63e99f05ca6634ad3b686987b7366d;p=francis%2Fwinuae.git Custom chipset WIP updates. --- diff --git a/blitter.cpp b/blitter.cpp index c9725631..cbb6575d 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -913,7 +913,7 @@ static void blit_bltset(int con) blit_changed = true; if (blit_warned > 0) { write_log(_T("BLITTER: BLTCON0 %04x -> %04x BLTCON1 %04x -> %04x PC=%08x (%d %d)\n"), bltcon0_old, bltcon0, bltcon1_old, bltcon1, M68K_GETPC, current_hpos(), vpos); - blitter_dump(); + //blitter_dump(); blitshifterdebug(bltcon0_old, false); blit_warned--; //activate_debugger(); @@ -969,7 +969,7 @@ static void blit_bltset(int con) } blit_dof = 0; - if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) { + if ((bltcon1 & 0x80) && ecs_agnus) { blit_dof = 1; debugtest(DEBUGTEST_BLITTER, _T("ECS BLTCON1 DOFF-bit set\n")); if (log_blitter & 16) diff --git a/cfgfile.cpp b/cfgfile.cpp index a3a7b0e2..d30f8b4c 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -354,6 +354,8 @@ static const TCHAR *obsolete[] = { _T("compforcesettings"), _T("comp_catchdetect"), + _T("hblank_glitch"), + NULL }; @@ -2529,7 +2531,6 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_bool(f, _T("z3_autoconfig"), p->cs_z3autoconfig); cfgfile_dwrite_bool(f, _T("1mchipjumper"), p->cs_1mchipjumper); cfgfile_dwrite_bool(f, _T("color_burst"), p->cs_color_burst); - cfgfile_dwrite_bool(f, _T("hblank_glitch"), p->cs_ocshblankbug); cfgfile_dwrite_bool(f, _T("toshiba_gary"), p->cs_toshibagary); cfgfile_dwrite_bool(f, _T("rom_is_slow"), p->cs_romisslow); cfgfile_dwrite_str(f, _T("ciaa_type"), ciatype[p->cs_ciatype[0]]); @@ -5546,7 +5547,6 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH || cfgfile_yesno(option, value, _T("ics_agnus"), &p->cs_dipagnus) || cfgfile_yesno(option, value, _T("z3_autoconfig"), &p->cs_z3autoconfig) || cfgfile_yesno(option, value, _T("color_burst"), &p->cs_color_burst) - || cfgfile_yesno(option, value, _T("hblank_glitch"), &p->cs_ocshblankbug) || cfgfile_yesno(option, value, _T("toshiba_gary"), &p->cs_toshibagary) || cfgfile_yesno(option, value, _T("rom_is_slow"), &p->cs_romisslow) || cfgfile_yesno(option, value, _T("1mchipjumper"), &p->cs_1mchipjumper) @@ -8013,7 +8013,6 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->cs_ciatodbug = false; p->cs_unmapped_space = 0; p->cs_color_burst = false; - p->cs_ocshblankbug = false; p->cs_ciatype[0] = 0; p->cs_ciatype[1] = 0; @@ -9031,7 +9030,6 @@ int built_in_chipset_prefs (struct uae_prefs *p) p->cs_1mchipjumper = false; p->cs_unmapped_space = 0; p->cs_color_burst = false; - p->cs_ocshblankbug = false; p->cs_romisslow = false; p->cs_toshibagary = false; p->cs_ciatype[0] = p->cs_ciatype[1] = 0; diff --git a/custom.cpp b/custom.cpp index 93adae57..6b0d9a6b 100644 --- a/custom.cpp +++ b/custom.cpp @@ -144,6 +144,7 @@ static bool graphicsbuffer_retry; static int cia_hsync; static bool toscr_scanline_complex_bplcon1, toscr_scanline_complex_bplcon1_off; static int toscr_hend; +int display_reset; #define LOF_TOGGLES_NEEDED 3 //#define NLACE_CNT_NEEDED 50 @@ -328,7 +329,7 @@ static int maxvpos_stored, maxhpos_stored; uae_u16 hsstop, hsstop_detect, hsstrt; static uae_u16 hbstop, hbstrt; static uae_u16 vsstop, vsstrt; -static uae_u16 vbstop, vbstopm1, vbstrt; +static uae_u16 vbstop, vbstrt; static uae_u16 hcenter, hcenter_v2, hcenter_v2_end; 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; @@ -1700,9 +1701,9 @@ static void update_mirrors(void) ecs_agnus = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) != 0; ecs_denise = (currprefs.chipset_mask & CSMASK_ECS_DENISE) != 0; direct_rgb = aga_mode; - if (currprefs.chipset_mask & CSMASK_AGA) { + if (aga_mode) { sprite_sprctlmask = 0x01 | 0x08 | 0x10; - } else if (currprefs.chipset_mask & CSMASK_ECS_DENISE) { + } else if (ecs_denise) { sprite_sprctlmask = 0x01 | 0x10; } else { sprite_sprctlmask = 0x01; @@ -1935,19 +1936,20 @@ static int fetch_warn(int nr, int hpos, bool *addmodulop) { static int warned1 = 30, warned2 = 30; int add = fetchmode_bytes; + // fake add value must not be large enough for high word to change if (cycle_line_slot[hpos] == CYCLE_STROBE) { if (warned1 >= 0) { write_log(_T("WARNING: BPL strobe refresh conflict, hpos %02X!\n"), hpos); warned1--; } *addmodulop = false; - add = refptr_val; + add = refptr_val & 0x0ffe; } else { if (warned2 >= 0) { warned2--; write_log(_T("WARNING: BPL refresh conflict, hpos %02X!\n"), hpos); } - add = refptr_val; + add = refptr_val & 0x0ffe; *addmodulop = false; } return add; @@ -4611,9 +4613,15 @@ static void reset_decisions_scanline_start(void) } } - if (!ecs_denise && currprefs.cs_ocshblankbug) { - if (vb_start_line == 2 + vblank_extraline) { - record_color_change2(0, 0, COLOR_CHANGE_BLANK | 1); + if (!ecs_denise) { + if (currprefs.cs_dipagnus || !ecs_agnus) { + if (vb_start_line == 2 + vblank_extraline) { + record_color_change2(0, 0, COLOR_CHANGE_BLANK | 1); + } + } else { + if (vb_start_line == 1 + vblank_extraline) { + record_color_change2(0, 0, COLOR_CHANGE_BLANK | 1); + } } if (vb_end_next_line) { record_color_change2(0, 0, COLOR_CHANGE_BLANK | 0); @@ -4682,12 +4690,17 @@ static void reset_decisions_hsync_start(void) 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; - thisline_decision.vb = vb_start_line > 1 + vblank_extraline ? 0 : 1; + if (!aga_mode && ecs_denise && exthblank) { + // ECS Denise + EXTHBLANK: VBLANK blanking is always disabled + thisline_decision.vb = 1; + } else { + thisline_decision.vb = vb_start_line > 1 + vblank_extraline ? 0 : 1; + } // if programmed vblank if (!thisline_decision.vb && (beamcon0 & 0x1000) && ecs_agnus) { thisline_decision.vb |= 2; } - if (!ecs_denise && vb_end_line && currprefs.cs_ocshblankbug) { + if (!ecs_denise && vb_end_line) { thisline_decision.vb = 1; } #endif @@ -4843,26 +4856,20 @@ void compute_vsynctime(void) } vsynctimebase_orig = vsynctimebase; -#if 0 -if (!picasso_on) { - updatedisplayarea(); -} -#endif - -if (islinetoggle()) { - shpos += 0.5; -} -if (interlace_seen) { - svpos += 0.5; -} else if (lof_current) { - svpos += 1.0; -} -if (currprefs.produce_sound > 1) { - double clk = svpos * shpos * fake_vblank_hz; - write_log(_T("SNDRATE %.1f*%.1f*%.6f=%.6f\n"), svpos, shpos, fake_vblank_hz, clk); - devices_update_sound(clk, syncadjust); -} -devices_update_sync(svpos, syncadjust); + if (islinetoggle()) { + shpos += 0.5; + } + if (interlace_seen) { + svpos += 0.5; + } else if (lof_current) { + svpos += 1.0; + } + if (currprefs.produce_sound > 1) { + double clk = svpos * shpos * fake_vblank_hz; + write_log(_T("SNDRATE %.1f*%.1f*%.6f=%.6f\n"), svpos, shpos, fake_vblank_hz, clk); + devices_update_sound(clk, syncadjust); + } + devices_update_sync(svpos, syncadjust); } void getsyncregisters(uae_u16 *phsstrt, uae_u16 *phsstop, uae_u16 *pvsstrt, uae_u16 *pvsstop) @@ -4929,7 +4936,7 @@ static void checklacecount(bool lace) static void set_hcenter(void) { - if (!aga_mode && ecs_denise && (bplcon0 & 1)) { + if (!aga_mode && ecs_denise && (bplcon0 & 1) && (bplcon3 & 1)) { if (beamcon0 & 0x0210) { hcenter_v2 = (hcenter & 0xff) << CCK_SHRES_SHIFT; } else { @@ -5399,6 +5406,12 @@ static void init_hz(bool checkvposw) maxhpos = htotal + 1; } + // after vsync, it seems earlier possible visible line is vsync+3. + int vsync_startline = vsstrt + 3; + if (vsync_startline >= maxvpos) { + vsync_startline -= maxvpos; + } + maxhpos_display = AMIGA_WIDTH_MAX; maxvpos_nom = maxvpos; maxvpos_display = maxvpos; @@ -5466,9 +5479,9 @@ static void init_hz(bool checkvposw) } if ((beamcon0 & 0x1000) && (beamcon0 & (0x0200 | 0x0010))) { // VARVBEN + VARVSYEN|VARCSYEN - minfirstline = vsstop; + minfirstline = vsync_startline; if (minfirstline > maxvpos / 2) { - minfirstline = vsstop; + minfirstline = vsync_startline; } minfirstline++; firstblankedline = vbstrt; @@ -5498,9 +5511,6 @@ static void init_hz(bool checkvposw) } else { maxvpos_display_vsync = 3; minfirstline -= eh / 2; - if (minfirstline < 8) { - minfirstline = 8; - } } } @@ -5511,9 +5521,6 @@ static void init_hz(bool checkvposw) if (minfirstline < 1) { minfirstline = 1; } - if (!(beamcon0 & 0x80) && minfirstline < 8 && !eh) { - minfirstline = 8; - } if (minfirstline >= maxvpos) { minfirstline = maxvpos - 1; @@ -5528,39 +5535,23 @@ static void init_hz(bool checkvposw) } if (beamcon0 & (0x0200 | 0x0010)) { - if (maxvpos_display_vsync >= vsstop - 3) { - maxvpos_display_vsync = vsstop - (3 + 1); + if (maxvpos_display_vsync >= vsstrt) { + maxvpos_display_vsync = vsstrt; } if (maxvpos_display_vsync < 0) { maxvpos_display_vsync = 0; } - if (minfirstline <= vsstop) { - minfirstline = vsstop + 1; + if (minfirstline <= vsync_startline) { + minfirstline = vsync_startline; } } - vbstopm1 = vbstop - 1; - if (vbstopm1 < 0) { - vbstopm1 += maxvpos; - } - if (beamcon0 & 0x80) { vblank_hz_nom = vblank_hz = clk / (maxvpos * maxhpos); vblank_hz_shf = vblank_hz; vblank_hz_lof = clk / ((maxvpos + 1) * maxhpos); vblank_hz_lace = clk / ((maxvpos + 0.5) * maxhpos); - if (beamcon0 & (0x0200 | 0x0010)) { - minfirstline = vsstop; - if (minfirstline > vtotal / 2) { - minfirstline = 1; - } - firstblankedline = vsstrt; - if (firstblankedline < vtotal / 2) { - firstblankedline = maxvpos + 1; - } - } - maxvpos_nom = maxvpos; maxvpos_display = maxvpos; equ_vblank_endline = -1; @@ -5624,6 +5615,7 @@ static void init_hz(bool checkvposw) compute_framesync(); devices_syncchange(); + display_reset = 2; #ifdef PICASSO96 init_hz_p96(0); @@ -5658,8 +5650,14 @@ static void calcdiw(void) // ECS Agnus/AGA: DIWHIGH vertical high bits. if (diwhigh_written && ecs_agnus) { - vstrt |= (diwhigh & 7) << 8; - vstop |= ((diwhigh >> 8) & 7) << 8; + if (aga_mode) { + vstrt |= (diwhigh & 7) << 8; + vstop |= ((diwhigh >> 8) & 7) << 8; + } else { + // ECS Agnus has undocumented V11! + vstrt |= (diwhigh & 15) << 8; + vstop |= ((diwhigh >> 8) & 15) << 8; + } } else { if ((vstop & 0x80) == 0) vstop |= 0x100; @@ -5858,8 +5856,6 @@ static bool hsyncdelay(void) #define CPU_ACCURATE (currprefs.cpu_model < 68020 || (currprefs.cpu_model == 68020 && currprefs.cpu_memory_cycle_exact)) -#define VPOS_INC_DELAY (CPU_ACCURATE ? 1 : 0) - static void vb_check(void) { // A1000 Agnus VBSTRT=first line, OCS and later: VBSTRT=last line @@ -5880,6 +5876,18 @@ static void vb_check(void) } } +static void vhpos_adj(uae_u16 *hpp, uae_u16 *vpp) +{ + uae_u16 hp = *hpp; + uae_u16 vp = *vpp; + if (hp == 0) { + // HP=0: VP = previous line. + vp = vpos_prev; + } + *hpp = hp; + *vpp = vp; +} + static uae_u16 VPOSR(void) { unsigned int csbit = 0; @@ -5893,12 +5901,8 @@ static uae_u16 VPOSR(void) lof = lof ? 0 : 1; } } - if (hp >= maxhpos + VPOS_INC_DELAY) { - vp++; - if (vp >= maxvpos + lof_store) { - vp = 0; - } - } + vhpos_adj(&hp, &vp); + vp = (vp >> 8) & 7; if (currprefs.cs_agnusrev >= 0) { @@ -6003,26 +6007,17 @@ static void VHPOSW(uae_u16 v) #endif } -static uae_u16 VHPOSR (void) +static uae_u16 VHPOSR(void) { static uae_u16 oldhp; uae_u16 vp = GETVPOS(); uae_u16 hp = GETHPOS(); - if (hp >= maxhpos) { - hp -= maxhpos; - // vpos increases when hp==1, not when hp==0 - if (hp >= VPOS_INC_DELAY) { - vp++; - if (vp >= maxvpos + lof_store) { - vp = 0; - } - } - } + vhpos_adj(&hp, &vp); vp <<= 8; - if (hsyncdelay ()) { + if (hsyncdelay()) { // fake continuously changing hpos in fastest possible modes hp = oldhp % maxhpos; oldhp++; @@ -6471,7 +6466,7 @@ bool INTREQ_0(uae_u16 v) serial_rbf_clear(); } - if ((v & 0x8000) && old != v) { + if (old != v) { doint_delay(); } return true; @@ -6501,9 +6496,9 @@ static void ADKCON(int hpos, uae_u16 v) static void check_harddis(void) { // VARBEAMEN, HARDDIS, SHRES, UHRES - harddis_h = ecs_agnus && ((new_beamcon0 & 0x80) || (new_beamcon0 & 0x4000) || (bplcon0 & 0x40) || (bplcon0 & 0x80)); + harddis_h = ecs_agnus && ((new_beamcon0 & 0x0080) || (new_beamcon0 & 0x4000) || (bplcon0 & 0x0040) || (bplcon0 & 0x0080)); // VARBEAMEN, VARVBEN, HARDDIS - harddis_v = ecs_agnus && ((new_beamcon0 & 0x80) || (new_beamcon0 & 0x1000) || (new_beamcon0 & 0x4000)); + harddis_v = ecs_agnus && ((new_beamcon0 & 0x0080) || (new_beamcon0 & 0x1000) || (new_beamcon0 & 0x4000)); } static void BEAMCON0(int hpos, uae_u16 v) @@ -6935,7 +6930,7 @@ static void DIWHIGH(int hpos, uae_u16 v) return; } if (!aga_mode) { - v &= ~(0x0008 | 0x0010 | 0x1000 | 0x0800); + v &= ~(0x0010 | 0x1000); } v &= ~(0x8000 | 0x4000 | 0x0080 | 0x0040); if (diwhigh_written && diwhigh == v) { @@ -8224,6 +8219,9 @@ static void do_copper_fetch(int hpos, uae_u8 id) alloc_cycle(hpos, CYCLE_COPPER); cop_state.ip += 2; +#ifdef DEBUGGER + uaecptr debugip = cop_state.ip; +#endif cop_state.ignore_next = 0; if (cop_state.ir[1] & 1) { cop_state.state = COP_skip_in2; @@ -8234,6 +8232,8 @@ static void do_copper_fetch(int hpos, uae_u8 id) cop_state.vcmp = (cop_state.ir[0] & (cop_state.ir[1] | 0x8000)) >> 8; cop_state.hcmp = (cop_state.ir[0] & cop_state.ir[1] & 0xFE); + record_copper(debugip - 4, debugip, cop_state.ir[0], cop_state.ir[1], hpos, vpos); + } else { // MOVE uae_u16 reg = cop_state.ir[0] & 0x1FE; @@ -9031,6 +9031,15 @@ static void maybe_process_pull_audio(void) audio_finish_pull(); } +static bool crender_screen(int monid, int mode, bool immediate) +{ + bool v = render_screen(monid, mode, immediate); + if (display_reset > 0) { + display_reset--; + } + return v; +} + // moving average algorithm #define MAVG_MAX_SIZE 128 struct mavg_data @@ -9092,7 +9101,7 @@ static bool framewait(void) curr_time = read_processor_time(); vsyncwaittime = vsyncmaxtime = curr_time + vsynctimebase; if (!frame_rendered && !ad->picasso_on) { - frame_rendered = render_screen(0, 1, false); + frame_rendered = crender_screen(0, 1, false); } start = read_processor_time(); @@ -9164,7 +9173,7 @@ static bool framewait(void) if (currprefs.m68k_speed < 0 && !cpu_sleepmode && !currprefs.cpu_memory_cycle_exact) { if (!frame_rendered && !ad->picasso_on) - frame_rendered = render_screen(0, 1, false); + frame_rendered = crender_screen(0, 1, false); if (currprefs.m68k_speed_throttle) { // this delay can safely overshoot frame time by 1-2 ms, following code will compensate for it. @@ -9210,7 +9219,7 @@ static bool framewait(void) start = read_processor_time(); if (!frame_rendered && !ad->picasso_on) { - frame_rendered = render_screen(0, 1, false); + frame_rendered = crender_screen(0, 1, false); t = read_processor_time() - start; } if (!currprefs.cpu_thread) { @@ -9316,7 +9325,8 @@ static void fpscounter(bool frameok) } // vsync functions that are not hardware timing related -// called when display is blanked, not necessarily last line but line 0 or later. +// called when vsync starts which is not necessarily last line +// it can line 0 or even later. static void vsync_handler_render(void) { struct amigadisplay *ad = &adisplays[0]; @@ -9356,15 +9366,6 @@ static void vsync_handler_render(void) cpu_stopped_lines = 0; #endif - if (bogusframe > 0) { - bogusframe--; - } - - config_check_vsync(); - if (timehack_alive > 0) { - timehack_alive--; - } - #ifdef PICASSO96 if (isvsync_rtg() >= 0) { rtg_vsync(); @@ -9384,7 +9385,7 @@ static void vsync_handler_render(void) if (!ad->picasso_on) { if (!frame_rendered && vblank_hz_state) { - frame_rendered = render_screen(0, 1, false); + frame_rendered = crender_screen(0, 1, false); } if (frame_rendered && !frame_shown) { frame_shown = show_screen_maybe(0, isvsync_chipset () >= 0); @@ -9396,15 +9397,17 @@ static void vsync_handler_render(void) bool waspaused = false; while (handle_events()) { if (!waspaused) { - render_screen(0, 1, true); - show_screen(0, 0); + if (crender_screen(0, 1, true)) { + show_screen(0, 0); + } waspaused = true; } // we are paused, do all config checks but don't do any emulation if (vsync_handle_check()) { redraw_frame(); - render_screen(0, 1, true); - show_screen(0, 0); + if (crender_screen(0, 1, true)) { + show_screen(0, 0); + } } config_check_vsync(); } @@ -9429,7 +9432,6 @@ static void vsync_handler_render(void) nextline_how = nln_normal; - vsync_handle_check(); //checklacecount (bplcon0_interlace_seen || lof_lace); } @@ -9447,15 +9449,12 @@ static void vsync_display_render(void) static void vsync_check_vsyncmode(void) { if (varsync_changed == 1) { - // render screen (minus extra lines) because mode is going to change and we don't want black screen flash - vsync_display_render(); init_hz_normal(); } else if (vpos_count > 0 && abs(vpos_count - vpos_count_diff) > 1 && vposw_change < 4) { - vsync_display_render(); init_hz_vposw(); } else if (interlace_changed || changed_chipset_refresh() || lof_changed) { - vsync_display_render(); compute_framesync(); + display_reset = 2; } if (varsync_changed > 0) { varsync_changed--; @@ -9569,14 +9568,26 @@ static void vsync_handler_post(void) varsync_changed = 2; } } + vsync_check_vsyncmode(); + if (bogusframe > 0) { + bogusframe--; + } + + config_check_vsync(); + if (timehack_alive > 0) { + timehack_alive--; + } + lof_changed = 0; vposw_change = 0; bplcon0_interlace_seen = false; COPJMP(1, 1); + vsync_handle_check(); + init_hardware_frame(); vsync_cycles = get_cycles(); @@ -9882,7 +9893,7 @@ static bool is_custom_vsync (void) static bool do_render_slice(int mode, int slicecnt, int lastline) { draw_lines(lastline, slicecnt); - render_screen(0, mode, true); + crender_screen(0, mode, true); return true; } @@ -10057,7 +10068,7 @@ static void hsync_handlerh(bool onvsync) hpos_hsync_extra = 0; estimate_last_fetch_cycle(hpos); - if (vb_end_line && !ecs_denise && currprefs.cs_ocshblankbug) { + if (vb_end_line && !ecs_denise) { record_color_change2(hpos, 0, COLOR_CHANGE_BLANK | 1); } @@ -10937,7 +10948,8 @@ static void hsync_handler_post (bool onvsync) } // vblank interrupt = next line after VBSTRT if (vb_start_line == 1) { - send_interrupt(5, 1 * CYCLE_UNIT); + // first refresh (strobe) slot triggers vblank interrupt + send_interrupt(5, REFRESH_FIRST_HPOS * CYCLE_UNIT); } // lastline - 1? if (vpos + 1 == maxvpos + lof_store || vpos + 1 == maxvpos + lof_store + 1) { @@ -10984,7 +10996,11 @@ static void hsync_handler_post (bool onvsync) vb_start_line = 1; vb_state = true; } - if (vbstopm1 == vpos) { + int vbs = vbstop - 1; + if (vbs < 0) { + vbs += maxvpos; + } + if (vbs == vpos) { vbstop_m = vpos; vb_end_line = true; vb_state = false; @@ -11038,6 +11054,7 @@ static void hsync_handler_post (bool onvsync) vs_state_hw = false; } } + if (new_beamcon0 & (0x0200 | 0x0010)) { vs_state_on = vs_state; } else { @@ -11256,7 +11273,7 @@ static void hsync_handler_post (bool onvsync) vsync_rendered = true; vsync_handle_redraw (lof_store, lof_changed, bplcon0, bplcon3); if (vblank_hz_state) { - frame_rendered = render_screen(1, true); + frame_rendered = crender_screen(1, true); } end = read_processor_time (); frameskiptime += end - start; @@ -11402,8 +11419,10 @@ void custom_reset(bool hardreset, bool keyboardreset) hbstop_v2 = 0; hcenter_v2 = 0; set_hcenter(); + display_reset = 1; if (!savestate_state) { + refptr_val = 0; cia_hsync = 0; extra_cycle = 0; hsync_counter = 0; @@ -12982,7 +13001,6 @@ void check_prefs_changed_custom (void) currprefs.cs_z3autoconfig = changed_prefs.cs_z3autoconfig; currprefs.cs_bytecustomwritebug = changed_prefs.cs_bytecustomwritebug; currprefs.cs_color_burst = changed_prefs.cs_color_burst; - currprefs.cs_ocshblankbug = changed_prefs.cs_ocshblankbug; currprefs.cs_romisslow = changed_prefs.cs_romisslow; currprefs.cs_toshibagary = changed_prefs.cs_toshibagary; currprefs.cs_unmapped_space = changed_prefs.cs_unmapped_space; diff --git a/drawing.cpp b/drawing.cpp index d79129d5..37ee9dc7 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -497,15 +497,23 @@ static void set_vblanking_limits(void) vblank_bottom_stop = visible_bottom_stop; } - bool hardwired = false; + bool hardwired = true; if (ecs_agnus) { hardwired = (new_beamcon0 & 0x1000) == 0; } if (hardwired) { int vbstrt = vblank_firstline_hw; + if (!ecs_denise) { + vbstrt--; + } int vbstop = maxvpos + lof_store; - if (currprefs.cs_dipagnus) { + if (!ecs_denise && !ecs_agnus) { vbstop++; + } else if (ecs_agnus && !ecs_denise) { + // hide hblank bug by faking vblank start 1 line earlier + if (currprefs.gfx_overscanmode < OVERSCANMODE_BROADCAST) { + vbstop--; + } } if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) { int mult = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 5; @@ -3210,6 +3218,7 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker int lastpos = visible_left_border; int endpos = visible_left_border + vidinfo->drawbuffer.inwidth; + extborder = false; // reset here because it always have start and end in same scanline for (i = dip_for_drawing->first_color_change; i <= dip_for_drawing->last_color_change; i++) { int regno = curr_color_changes[i].regno; uae_u32 value = curr_color_changes[i].value; @@ -4288,7 +4297,7 @@ void draw_lines(int end, int section) int section_color_cnt = 4; vidinfo->outbuffer = vb; - if (!lockscr(vb, false, vb->last_drawn_line ? false : true)) + if (!lockscr(vb, false, vb->last_drawn_line ? false : true, display_reset > 0)) return; set_vblanking_limits(); @@ -4435,7 +4444,7 @@ static void finish_drawing_frame(bool drawlines) return; } - if (!lockscr(vb, false, true)) { + if (!lockscr(vb, false, true, display_reset > 0)) { notice_screen_contents_lost(monid); return; } @@ -4455,7 +4464,7 @@ static void finish_drawing_frame(bool drawlines) bool locked = true; bool multimon = currprefs.monitoremu_mon != 0; if (multimon) { - locked = lockscr(out, false, true); + locked = lockscr(out, false, true, display_reset > 0); outvi->xchange = vidinfo->xchange; outvi->ychange = vidinfo->ychange; } else { @@ -4530,7 +4539,7 @@ static void finish_drawing_frame(bool drawlines) vidinfo->drawbuffer.tempbufferinuse = true; } - unlockscr(vb, -1, -1); + unlockscr(vb, display_reset ? -2 : -1, -1); } void check_prefs_picasso(void) @@ -4881,6 +4890,7 @@ void reset_drawing(void) exthblank = false; exthblanken = false; extborder = false; + display_reset = 1; lores_reset (); diff --git a/include/custom.h b/include/custom.h index 15dbd371..608daebe 100644 --- a/include/custom.h +++ b/include/custom.h @@ -136,6 +136,7 @@ extern float hblank_hz; extern int vblank_skip, doublescan; extern int programmedmode; extern int vblank_firstline_hw; +extern int display_reset; #define DMA_AUD0 0x0001 #define DMA_AUD1 0x0002 diff --git a/include/options.h b/include/options.h index fc366702..9f8dcbbf 100644 --- a/include/options.h +++ b/include/options.h @@ -691,7 +691,6 @@ struct uae_prefs { int cs_hacks; int cs_ciatype[2]; int cs_kbhandshake; - bool cs_ocshblankbug; struct boardromconfig expansionboard[MAX_EXPANSION_BOARDS]; diff --git a/include/xwin.h b/include/xwin.h index 0775f0c0..70f88c00 100644 --- a/include/xwin.h +++ b/include/xwin.h @@ -53,7 +53,7 @@ extern bool render_screen(int monid, int, bool); extern void show_screen(int monid, int mode); extern bool show_screen_maybe(int monid, bool); -extern int lockscr(struct vidbuffer*, bool, bool); +extern int lockscr(struct vidbuffer*, bool, bool, bool); extern void unlockscr(struct vidbuffer*, int, int); extern bool target_graphics_buffer_update(int monid); extern float target_adjust_vblank_hz(int monid, float); diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 83e4c7ce..870bb4f3 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -157,7 +157,7 @@ struct d3dstruct IDirect3DDevice9 *d3ddev; IDirect3DDevice9Ex *d3ddevex; D3DSURFACE_DESC dsdbb; - LPDIRECT3DTEXTURE9 texture, sltexture, ledtexture, blanktexture; + LPDIRECT3DTEXTURE9 texture1, texture2, usetexture, sltexture, ledtexture, blanktexture; LPDIRECT3DTEXTURE9 mask2texture, mask2textureleds[9], mask2textureled_power_dim; int mask2textureledoffsets[9 * 2]; IDirect3DQuery9 *query; @@ -181,6 +181,7 @@ struct d3dstruct volatile bool fakemode; uae_u8 *fakebitmap; + int fakelock; uae_thread_id fakemodetid; D3DXMATRIXA16 m_matProj, m_matProj2, m_matProj_out; @@ -1289,8 +1290,9 @@ static int createamigatexture (struct d3dstruct *d3d, int w, int h) { HRESULT hr; - d3d->texture = createtext (d3d, w, h, d3d->tformat); - if (!d3d->texture) + d3d->texture1 = createtext(d3d, w, h, d3d->tformat); + d3d->texture2 = createtext(d3d, w, h, d3d->tformat); + if (!d3d->texture1 || !d3d->texture2) return 0; write_log (_T("%s: %d*%d main texture, depth %d\n"), D3DHEAD, w, h, d3d->t_depth); if (d3d->psActive) { @@ -2359,9 +2361,13 @@ static void settransform2 (struct d3dstruct *d3d, struct shaderdata *s) static void freetextures (struct d3dstruct *d3d) { - if (d3d->texture) { - d3d->texture->Release (); - d3d->texture = NULL; + if (d3d->texture2) { + d3d->texture2->Release(); + d3d->texture2 = NULL; + } + if (d3d->texture1) { + d3d->texture1->Release(); + d3d->texture1 = NULL; } for (int i = 0; i < MAX_SHADERS; i++) { struct shaderdata *s = &d3d->shaders[i]; @@ -3424,10 +3430,10 @@ static void D3D_render2(struct d3dstruct *d3d, int mode) { struct AmigaMonitor *mon = &AMonitors[d3d - d3ddata]; HRESULT hr; - LPDIRECT3DTEXTURE9 srctex = d3d->texture; + LPDIRECT3DTEXTURE9 srctex = d3d->usetexture; UINT uPasses, uPass; - if (!isd3d (d3d) || !d3d->texture) + if (!isd3d (d3d) || !srctex) return; bool normalrender = mode < 0 || (mode & 1); @@ -3776,7 +3782,7 @@ static void xD3D_flushtexture(int monid, int miny, int maxy) { struct d3dstruct *d3d = &d3ddata[monid]; - if (d3d->fakemode || d3d->fulllocked || !d3d->texture || d3d->renderdisabled) + if (d3d->fakemode || d3d->fulllocked || !d3d->texture1 || d3d->renderdisabled) return; if (miny >= 0 && maxy >= 0) { RECT r; @@ -3786,7 +3792,7 @@ static void xD3D_flushtexture(int monid, int miny, int maxy) r.top = miny <= 0 ? 0 : miny; r.bottom = maxy <= d3d->tin_h ? maxy : d3d->tin_h; if (r.top <= r.bottom) { - HRESULT hr = d3d->texture->AddDirtyRect (&r); + HRESULT hr = d3d->texture1->AddDirtyRect (&r); if (FAILED (hr)) write_log (_T("%s: AddDirtyRect(): %s\n"), D3DHEAD, D3D_ErrorString (hr)); //write_log (_T("%d %d\n"), r.top, r.bottom); @@ -3799,13 +3805,22 @@ static void xD3D_unlocktexture(int monid, int y_start, int y_end) struct d3dstruct *d3d = &d3ddata[monid]; HRESULT hr; - if (!isd3d(d3d) || !d3d->texture) + if (!isd3d(d3d) || !d3d->texture1) + return; + + if (d3d->fakelock) { + d3d->fakelock--; return; + } if (d3d->locked) { + LPDIRECT3DTEXTURE9 tex = d3d->texture1; + if (d3d->locked == 2) { + tex = d3d->texture2; + } if (currprefs.leds_on_screen & (STATUSLINE_CHIPSET | STATUSLINE_RTG)) updateleds(d3d); - hr = d3d->texture->UnlockRect(0); + hr = tex->UnlockRect(0); if (y_start >= 0) xD3D_flushtexture(monid, y_start, y_end); } @@ -3813,7 +3828,7 @@ static void xD3D_unlocktexture(int monid, int y_start, int y_end) d3d->fulllocked = 0; } -static uae_u8 *xD3D_locktexture (int monid, int *pitch, int *height, bool fullupdate) +static uae_u8 *xD3D_locktexture (int monid, int *pitch, int *height, int fullupdate) { struct d3dstruct *d3d = &d3ddata[monid]; D3DLOCKED_RECT lock; @@ -3824,10 +3839,28 @@ static uae_u8 *xD3D_locktexture (int monid, int *pitch, int *height, bool fullup return d3d->fakebitmap; } + if (fullupdate < 0) { + if (d3d->usetexture == d3d->texture1) { + LPDIRECT3DTEXTURE9 tex1 = d3d->texture1; + LPDIRECT3DTEXTURE9 tex2 = d3d->texture2; + IDirect3DSurface9* s1, * s2; + if (SUCCEEDED(tex1->GetSurfaceLevel(0, &s1))) { + if (SUCCEEDED(tex2->GetSurfaceLevel(0, &s2))) { + HRESULT hr = d3d->d3ddev->StretchRect(s1, NULL, s2, NULL, D3DTEXF_NONE); + s2->Release(); + d3d->usetexture = tex2; + } + s1->Release(); + } + } + } else { + d3d->usetexture = d3d->texture1; + } + if (D3D_needreset (d3d) > 0) { return NULL; } - if (!isd3d (d3d) || !d3d->texture) + if (!isd3d (d3d)) return NULL; if (d3d->locked) { @@ -3835,9 +3868,15 @@ static uae_u8 *xD3D_locktexture (int monid, int *pitch, int *height, bool fullup return NULL; } + if (!d3d->texture1) { + *pitch = 0; + d3d->fakelock++; + return d3d->fakebitmap; + } + lock.pBits = NULL; lock.Pitch = 0; - hr = d3d->texture->LockRect (0, &lock, NULL, fullupdate ? D3DLOCK_DISCARD : D3DLOCK_NO_DIRTY_UPDATE); + hr = d3d->texture1->LockRect (0, &lock, NULL, fullupdate > 0 ? D3DLOCK_DISCARD : D3DLOCK_NO_DIRTY_UPDATE); if (FAILED (hr)) { write_log (_T("%s: LockRect failed: %s\n"), D3DHEAD, D3D_ErrorString (hr)); return NULL; @@ -3848,7 +3887,7 @@ static uae_u8 *xD3D_locktexture (int monid, int *pitch, int *height, bool fullup D3D_unlocktexture(monid, -1, -1); return NULL; } - d3d->fulllocked = fullupdate; + d3d->fulllocked = fullupdate > 0; *pitch = lock.Pitch; if (height) *height = d3d->tin_h; @@ -3886,7 +3925,7 @@ static bool xD3D_renderframe(int monid, int mode, bool immediate) if (d3d->fakemode) return true; - if (!isd3d (d3d) || !d3d->texture) + if (!isd3d (d3d) || !d3d->texture1 || !d3d->texture2) return false; if (d3d->filenotificationhandle != NULL) { @@ -4071,7 +4110,7 @@ LPDIRECT3DSURFACE9 D3D_capture(int monid, int *w, int *h, int *bits, bool render } ret = d3d->screenshotsurface; } else { - hr = d3d->texture->GetSurfaceLevel(0, &ret); + hr = d3d->texture1->GetSurfaceLevel(0, &ret); if (FAILED(hr)) { write_log(_T("%s: D3D_capture() GetSurfaceLevel() failed: %s\n"), D3DHEAD, D3D_ErrorString(hr)); return NULL; diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index fd420e84..e7c9d483 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -14,7 +14,7 @@ extern void(*D3D_refresh)(int); extern bool(*D3D_renderframe)(int, int,bool); extern void(*D3D_showframe)(int); extern void(*D3D_showframe_special)(int, int); -extern uae_u8* (*D3D_locktexture)(int, int*, int*, bool); +extern uae_u8* (*D3D_locktexture)(int, int*, int*, int); extern void(*D3D_unlocktexture)(int, int, int); extern void(*D3D_flushtexture)(int, int miny, int maxy); extern void(*D3D_guimode)(int, int); diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp index e53a7719..342200b3 100644 --- a/od-win32/direct3d11.cpp +++ b/od-win32/direct3d11.cpp @@ -47,7 +47,7 @@ void(*D3D_refresh)(int); bool(*D3D_renderframe)(int, int,bool); void(*D3D_showframe)(int); void(*D3D_showframe_special)(int, int); -uae_u8* (*D3D_locktexture)(int, int*, int*, bool); +uae_u8* (*D3D_locktexture)(int, int*, int*, int); void (*D3D_unlocktexture)(int, int, int); void (*D3D_flushtexture)(int, int miny, int maxy); void (*D3D_guimode)(int, int); @@ -1998,7 +1998,7 @@ static bool CreateTexture(struct d3d11struct *d3d) return false; } - ID3D11Texture2D* pSurface; + ID3D11Texture2D *pSurface; hr = d3d->m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast< void** >(&pSurface)); if (SUCCEEDED(hr)) { memset(&desc, 0, sizeof desc); @@ -4788,7 +4788,7 @@ static bool xD3D11_alloctexture(int monid, int w, int h) return true; } -static uae_u8 *xD3D11_locktexture(int monid, int *pitch, int *height, bool fullupdate) +static uae_u8 *xD3D11_locktexture(int monid, int *pitch, int *height, int fullupdate) { struct d3d11struct *d3d = &d3d11data[monid]; @@ -4822,6 +4822,10 @@ static void xD3D11_unlocktexture(int monid, int y_start, int y_end) d3d->m_deviceContext->Unmap(d3d->texture2dstaging, 0); + if (y_start < -1 || y_end < -1) { + return; + } + bool rtg = WIN32GFX_IsPicassoScreen(mon); if (((currprefs.leds_on_screen & STATUSLINE_CHIPSET) && !rtg) || ((currprefs.leds_on_screen & STATUSLINE_RTG) && rtg)) { d3d->osd.enabled = true; diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index dcb81a24..7d172300 100644 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -1149,7 +1149,6 @@ #define IDC_DBG_MEM 1756 #define IDC_CS_COMPOSITECOLOR 1756 #define IDC_DBG_DASM 1757 -#define IDC_CS_OCSHBLANKBUG 1757 #define IDC_DBG_MEMDOWNFAST 1758 #define IDC_CS_TOSHIBAGARY 1758 #define IDC_DBG_MEMTOPC 1759 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 426dfdbc..b0118c08 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -851,7 +851,6 @@ BEGIN CONTROL "KS ROM has Chip RAM speed",IDC_CS_ROMISSLOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,127,197,125,12 CONTROL "CIA 391078-01 [] CIA revision that can't read IO pin status in output mode",IDC_CS_CIA, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,197,125,12 - CONTROL "OCS H-Blank glitch",IDC_CS_OCSHBLANKBUG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,184,125,12 END IDD_AVIOUTPUT DIALOGEX 0, 0, 396, 316 diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index 7acc7ac7..e87b1426 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -1052,7 +1052,7 @@ void S2X_render(int monid, int y_start, int y_end) if (d3d) { if (D3D_restore) D3D_restore(monid, true); - surfstart = D3D_locktexture(monid, &pitch, &surf_height, y_start < 0); + surfstart = D3D_locktexture(monid, &pitch, &surf_height, y_start < -1 ? -1 : (y_start < 0 ? 1 : 0)); if (surfstart == NULL) return; } else { diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 3963c960..95a6315e 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -1601,7 +1601,7 @@ void unlockscr3d(struct vidbuffer *vb) } } -int lockscr(struct vidbuffer *vb, bool fullupdate, bool first) +int lockscr(struct vidbuffer *vb, bool fullupdate, bool first, bool skip) { struct AmigaMonitor *mon = &AMonitors[vb->monitor_id]; int ret = 0; @@ -1620,7 +1620,7 @@ int lockscr(struct vidbuffer *vb, bool fullupdate, bool first) ret = 1; } else { ret = 0; - vb->bufmem = D3D_locktexture(vb->monitor_id, &vb->rowbytes, NULL, fullupdate); + vb->bufmem = D3D_locktexture(vb->monitor_id, &vb->rowbytes, NULL, skip ? -1 : (fullupdate ? 1 : 0)); if (vb->bufmem) { if (first) init_row_map(); @@ -1661,7 +1661,7 @@ void flush_clear_screen (struct vidbuffer *vb) { if (!vb) return; - if (lockscr(vb, true, true)) { + if (lockscr(vb, true, true, false)) { int y; for (y = 0; y < vb->height_allocated; y++) { memset(vb->bufmem + y * vb->rowbytes, 0, vb->width_allocated * vb->pixbytes); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index c3f2daed..7f878c95 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -9029,7 +9029,6 @@ static void values_to_chipsetdlg2 (HWND hDlg) CheckDlgButton(hDlg, IDC_CS_1MCHIPJUMPER, workprefs.cs_1mchipjumper || workprefs.chipmem.size >= 0x100000); CheckDlgButton(hDlg, IDC_CS_BYTECUSTOMWRITEBUG, workprefs.cs_bytecustomwritebug); CheckDlgButton(hDlg, IDC_CS_COMPOSITECOLOR, workprefs.cs_color_burst); - CheckDlgButton(hDlg, IDC_CS_OCSHBLANKBUG, workprefs.cs_ocshblankbug); CheckDlgButton(hDlg, IDC_CS_TOSHIBAGARY, workprefs.cs_toshibagary); CheckDlgButton(hDlg, IDC_CS_ROMISSLOW, workprefs.cs_romisslow); CheckDlgButton(hDlg, IDC_CS_CIA, workprefs.cs_ciatype[0]); @@ -9122,7 +9121,6 @@ static void values_from_chipsetdlg2 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM workprefs.cs_1mchipjumper = ischecked(hDlg, IDC_CS_1MCHIPJUMPER); workprefs.cs_bytecustomwritebug = ischecked(hDlg, IDC_CS_BYTECUSTOMWRITEBUG); workprefs.cs_color_burst = ischecked(hDlg, IDC_CS_COMPOSITECOLOR); - workprefs.cs_ocshblankbug = ischecked(hDlg, IDC_CS_OCSHBLANKBUG); workprefs.cs_toshibagary = ischecked(hDlg, IDC_CS_TOSHIBAGARY); workprefs.cs_romisslow = ischecked(hDlg, IDC_CS_ROMISSLOW); workprefs.cs_ciatype[0] = workprefs.cs_ciatype[1] = ischecked(hDlg, IDC_CS_CIA); @@ -9213,7 +9211,6 @@ static void enable_for_chipsetdlg2 (HWND hDlg) ew(hDlg, IDC_CS_1MCHIPJUMPER, e && workprefs.chipmem.size < 0x100000); ew(hDlg, IDC_CS_BYTECUSTOMWRITEBUG, e); ew(hDlg, IDC_CS_COMPOSITECOLOR, e); - ew(hDlg, IDC_CS_OCSHBLANKBUG, e); ew(hDlg, IDC_CS_TOSHIBAGARY, e); ew(hDlg, IDC_CS_ROMISSLOW, e); ew(hDlg, IDC_CS_UNMAPPED, e);