]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Ultra extreme overscan blanking and sync modes.
authorToni Wilen <twilen@winuae.net>
Sat, 11 Feb 2023 08:52:32 +0000 (10:52 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 11 Feb 2023 08:52:32 +0000 (10:52 +0200)
cfgfile.cpp
custom.cpp
drawing.cpp
include/drawing.h
od-win32/resources/resource.h
od-win32/win32gui.cpp

index 28b7693c7412e0300417ad26e1525a6e8fb6cd4e..696a6db1b8d865d698174dcbe5dfda5a72dc6785 100644 (file)
@@ -205,7 +205,7 @@ static const TCHAR *vsyncmodes[] = { _T("false"), _T("true"), _T("autoswitch"),
 static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 };
 static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), _T("direct3d11"), _T("direct3d11"), 0};
 static const TCHAR *filterapiopts[] = { _T("hardware"), _T("software"), 0 };
-static const TCHAR *overscanmodes[] = { _T("tv_narrow"), _T("tv_standard"), _T("tv_wide"), _T("overscan"), _T("broadcast"), _T("extreme"), _T("ultra"), NULL};
+static const TCHAR *overscanmodes[] = { _T("tv_narrow"), _T("tv_standard"), _T("tv_wide"), _T("overscan"), _T("broadcast"), _T("extreme"), _T("ultra"), _T("ultra_hv"), _T("ultra_csync"), NULL};
 static const TCHAR *dongles[] =
 {
        _T("none"),
index 38e4b32592796b8f8da20d42a4ddbfbfdec08639..d877436af2f48f01c9933758dd5ef0e3a94b5805 100644 (file)
@@ -193,22 +193,30 @@ static bool dmacon_bpl, vdiwstate_bpl;
 static uae_u32 cop1lc, cop2lc, copcon;
 
 /*
-* horizontal defaults
+* Horizontal defaults
+* 
 * 0x00   0 HCB
 * 0x01   1 HC1 (HSTART)
 * 0x09   9 VR1 (HBLANK start)
 * 0x12  18 SHS (Horizontal sync start)
-* 0x1a  26 VER1 PAL
+* 0x1a  26 VER1 PAL 
 * 0x1b  27 VER1 NTSC
 * 0x23  35 RHS (Horizontal sync end)
 * 0x73 115 VR2
 * 0x84 132 CEN (HCENTER)
-* 0x8c 140 VER2 PAL
+* 0x8c 140 VER2 PAL (CEN->VER2 = CSYNC qualising pulse 2)
 * 0x8d 141 VER2 NTSC
 * 0xe2 226 HC226 (short line, selected if LOL=1, NTSC only)
 * 0xe3 227 HC227 (NTSC long line/PAL)
 * 
-* vertical defaults
+* SHS->VER1 = CSYNC equalising pulse 1
+* CEN->VER2 = CSYNC equalising pulse 2
+* 
+* HC1->SHS = Inactivate part of CSYNC Vsync+Hsync pulse 1
+* VR2->CEN = Inactivate part of CSYNC Vsync+HSync pulse 2
+* 
+*
+* Vertical defaults
 * 
 * PAL
 * 
@@ -287,11 +295,6 @@ static uae_u32 cop1lc, cop2lc, copcon;
 * Switch DMACON BPLEN off, wait value to DDFSTRT that matches during current scanline,
 * switch BPLEN on: if OCS, bitplane DMA won't start, ECS/AGA: bitplane DMA starts.
 * 
-* 
-* 
-* 
-* 
-* 
 */
 
 
@@ -342,10 +345,12 @@ static int hsstop_detect, hsstop_detect2;
 static uae_u16 vsstop, vsstrt;
 static uae_u16 vbstop, vbstrt;
 static uae_u16 hcenter, hcenter_v2, hcenter_v2_end;
+static bool hcenter_active;
 static uae_u16 hbstop_v, hbstrt_v, hbstop_v2, hbstrt_v2;
+static uae_u16 hsstrt_v2, hsstop_v2;
 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 vs_state, vs_state_on, vs_state_on_old, vs_state_on_old2, vs_state_hw;
 static bool vb_end_next_line, vb_end_next_line2;
 static int vb_start_line;
 static bool ocs_blanked;
@@ -454,6 +459,7 @@ static int last_hdiw;
 static diw_states vdiwstate, hdiwstate, hdiwstate_conflict;
 static int bpl_hstart;
 static bool exthblank, exthblank_state, hcenterblank_state;
+static int hsyncdebug;
 static int last_diw_hpos, last_diw_hpos2;
 static int last_recorded_diw_hpos;
 static int last_hblank_start;
@@ -990,10 +996,84 @@ static void hblank_reset(int hblankpos)
        hb_last_diwlastword = hblankpos + 4;
 }
 
-static void record_color_change2(int hpos, int regno, uae_u32 value)
+static void addcc(int pos, int reg, int v)
 {
-       color_change *cc;
+       color_change *cc = &curr_color_changes[next_color_change++];
+       cc->linepos = pos;
+       cc->regno = reg;
+       cc->value = v;
+       cc++;
+       cc->regno = -1;
+}
+
+static void addccmp(int pos, int reg, int v, int chpos)
+{
+       if (pos < chpos && pos >= last_recorded_diw_hpos) {
+               addcc(pos, reg, v);
+       }
+}
 
+static void syncdebugmarkers(int chpos)
+{
+       if (hsyncdebug == 3) {
+               int ver1 = (beamcon0 & BEAMCON0_PAL) ? 26 : 27;
+               int ver2 = (beamcon0 & BEAMCON0_PAL) ? 140 : 141;
+               // CSYNC
+               if (vpos >= 8 || (beamcon0 & BEAMCON0_VARHSYEN)) {
+                       addccmp(hsstrt_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 1, chpos);
+                       addccmp(hsstop_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 0, chpos);
+               }
+               addccmp(hbstrt_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x204, 1, chpos);
+               addccmp(hbstop_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x204, 0, chpos);
+               if (!(beamcon0 & BEAMCON0_VARHSYEN)) {
+                       if (vpos == 0 || vpos == 1 || vpos == 5 || vpos == 6) {
+                               addccmp(18 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 1, chpos);
+                               addccmp(ver1 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 0, chpos);
+                               addccmp(132 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 1, chpos);
+                               addccmp(ver2 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 0, chpos);
+                       }
+                       if (vpos == 2) {
+                               addccmp((12 + maxhpos) << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 1, chpos);
+                               addccmp(ver1 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 0, chpos);
+                               addccmp(132 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 1, chpos);
+                       }
+                       if (vpos == 3 || vpos == 4) {
+                               addccmp((1 + maxhpos) << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 0, chpos);
+                               addccmp(18 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 1, chpos);
+                               addccmp(115 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 0, chpos);
+                               addccmp(132 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 1, chpos);
+                       }
+                       if (vpos == 7) {
+                               addccmp(18 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 1, chpos);
+                               addccmp(ver1 << CCK_SHRES_SHIFT, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 0, chpos);
+                       }
+               }
+       } else {
+               // H/V SYNC
+               if (hcenter_v2 < chpos && hcenter_v2 >= last_recorded_diw_hpos) {
+                       if (beamcon0 & BEAMCON0_PAL) {
+                               if (vs_state_on && !lof_display) {
+                                       addcc(hcenter_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x206, 0);
+                               } else if (!vs_state_on && vs_state_on_old && lof_display) {
+                                       addcc(hcenter_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x206, 1);
+                               }
+                       } else {
+                               if (vs_state_on && lof_display) {
+                                       addcc(hcenter_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x206, 0);
+                               } else if (!vs_state_on && vs_state_on_old && lof_display) {
+                                       addcc(hcenter_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x206, 1);
+                               }
+                       }
+               }
+               addccmp(hsstrt_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 1, chpos);
+               addccmp(hsstop_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x202, 0, chpos);
+               addccmp(hbstrt_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x204, 1, chpos);
+               addccmp(hbstop_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x204, 0, chpos);
+       }
+}
+
+static void record_color_change2(int hpos, int regno, uae_u32 value)
+{
        if (line_disabled) {
                return;
        }
@@ -1003,6 +1083,7 @@ static void record_color_change2(int hpos, int regno, uae_u32 value)
        }
 
        int pos = hpos < 0 ? -hpos : hpos_to_diwx(hpos);
+       int start_color_change = next_color_change;
 
        // AGA has extra hires pixel delay in color changes
        if ((regno < RECORDED_REGISTER_CHANGE_OFFSET || regno == RECORDED_REGISTER_CHANGE_OFFSET + 0x10c || regno == RECORDED_REGISTER_CHANGE_OFFSET + 0x201) && aga_mode) {
@@ -1026,31 +1107,21 @@ static void record_color_change2(int hpos, int regno, uae_u32 value)
                        pos += 2;
                        if ((value & 0x00ff) != (bplcon4 & 0x00ff)) {
                                // Sprite bank delay
-                               cc = &curr_color_changes[next_color_change];
-                               cc->linepos = pos;
-                               cc->regno = regno | 1;
-                               cc->value = value;
-                               next_color_change++;
+                               addcc(pos, regno | 1, value);
                        }
                        pos += 2;
                }
        }
 
        // HCENTER blanking (ECS Denise only)
-       if (hcenter_v2 && vs_state_on && lof_display) {
+       if (hcenter_active && vs_state_on && lof_display) {
                int chpos = pos;
                if (!hcenterblank_state && hcenter_v2 < chpos && hcenter_v2 >= last_recorded_diw_hpos) {
                        hcenterblank_state = true;
                        if ((bplcon0 & 1) && (bplcon3 & 1)) {
-                               cc = &curr_color_changes[next_color_change];
-                               cc->linepos = hcenter_v2;
-                               cc->regno = RECORDED_REGISTER_CHANGE_OFFSET + 0x200;
-                               cc->value = 1;
-                               next_color_change++;
-                               cc[1].regno = -1;
-                               last_recorded_diw_hpos = cc->linepos;
+                               addcc(hcenter_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x200, 1);
                                if (debug_dma) {
-                                       record_dma_event(DMA_EVENT_HBS, diw_to_hpos(cc->linepos), vpos);
+                                       record_dma_event(DMA_EVENT_HBS, diw_to_hpos(hcenter_v2), vpos);
                                }
                                thisline_changed = 1;
                        }
@@ -1058,15 +1129,9 @@ static void record_color_change2(int hpos, int regno, uae_u32 value)
                if (hcenterblank_state && hcenter_v2_end < chpos && hcenter_v2_end >= last_recorded_diw_hpos) {
                        hcenterblank_state = false;
                        if ((bplcon0 & 1) && (bplcon3 & 1)) {
-                               cc = &curr_color_changes[next_color_change];
-                               cc->linepos = hcenter_v2_end;
-                               cc->regno = RECORDED_REGISTER_CHANGE_OFFSET + 0x200;
-                               cc->value = 0;
-                               next_color_change++;
-                               cc[1].regno = -1;
-                               last_recorded_diw_hpos = cc->linepos;
+                               addcc(hcenter_v2_end, RECORDED_REGISTER_CHANGE_OFFSET + 0x200, 0);
                                if (debug_dma) {
-                                       record_dma_event(DMA_EVENT_HBE, diw_to_hpos(cc->linepos), vpos);
+                                       record_dma_event(DMA_EVENT_HBE, diw_to_hpos(hcenter_v2), vpos);
                                }
                                thisline_changed = 1;
                        }
@@ -1078,93 +1143,89 @@ static void record_color_change2(int hpos, int regno, uae_u32 value)
                // inject programmed hblank start and end in color changes
                if (hbstrt_v2 <= hbstop_v2) {
                        if (hbstrt_v2 < chpos && hbstrt_v2 >= last_recorded_diw_hpos) {
-                               cc = &curr_color_changes[next_color_change];
-                               cc->linepos = hbstrt_v2;
-                               cc->regno = RECORDED_REGISTER_CHANGE_OFFSET + 0x200;
-                               cc->value = 1;
-                               next_color_change++;
-                               cc[1].regno = -1;
+                               addcc(hbstrt_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x200, 1);
                                hblank_reset(hbstrt_v2);
                                exthblank_state = true;
-                               last_recorded_diw_hpos = cc->linepos;
-                               last_hblank_start = cc->linepos;
+                               last_hblank_start = hbstrt_v2;
                                if (debug_dma) {
-                                       record_dma_event(DMA_EVENT_HBS, diw_to_hpos(cc->linepos), vpos);
+                                       record_dma_event(DMA_EVENT_HBS, diw_to_hpos(hbstrt_v2), vpos);
                                }
                        }
                        if (hbstop_v2 < chpos && hbstop_v2 >= last_recorded_diw_hpos) {
                                // do_color_changes() HBLANK workaround
                                if (next_color_change == last_color_change && exthblank_state) {
-                                       cc = &curr_color_changes[next_color_change];
-                                       cc->linepos = 0;
-                                       cc->regno = RECORDED_REGISTER_CHANGE_OFFSET + 0x200;
-                                       cc->value = 1;
-                                       next_color_change++;
-                               }
-                               cc = &curr_color_changes[next_color_change];
-                               cc->linepos = hbstop_v2;
-                               cc->regno = RECORDED_REGISTER_CHANGE_OFFSET + 0x200;
-                               cc->value = 0;
-                               next_color_change++;
-                               cc[1].regno = -1;
+                                       addcc(0, RECORDED_REGISTER_CHANGE_OFFSET + 0x200, 1);
+                               }
+                               addcc(hbstop_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x200, 0);
                                exthblank_state = false;
-                               last_recorded_diw_hpos = cc->linepos;
                                if (debug_dma) {
-                                       record_dma_event(DMA_EVENT_HBE, diw_to_hpos(cc->linepos), vpos);
+                                       record_dma_event(DMA_EVENT_HBE, diw_to_hpos(hbstop_v2), vpos);
                                }
                        }
-               } else  if (hbstrt_v2 > hbstop_v2) { // equal: blank disable wins
+               } else if (hbstrt_v2 > hbstop_v2) { // equal: blank disable 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];
-                                       cc->linepos = 0;
-                                       cc->regno = RECORDED_REGISTER_CHANGE_OFFSET + 0x200;
-                                       cc->value = 1;
-                                       next_color_change++;
-                               }
-                               cc = &curr_color_changes[next_color_change];
-                               cc->linepos = hbstop_v2;
-                               cc->regno = RECORDED_REGISTER_CHANGE_OFFSET + 0x200;
-                               cc->value = 0;
-                               next_color_change++;
-                               cc[1].regno = -1;
+                                       addcc(0, RECORDED_REGISTER_CHANGE_OFFSET + 0x200, 1);
+                               }
+                               addcc(hbstop_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x200, 0);
                                exthblank_state = false;
-                               last_recorded_diw_hpos = cc->linepos;
                                if (debug_dma) {
-                                       record_dma_event(DMA_EVENT_HBE, diw_to_hpos(cc->linepos), vpos);
+                                       record_dma_event(DMA_EVENT_HBE, diw_to_hpos(hbstop_v2), vpos);
                                }
                        }
                        if (hbstrt_v2 < chpos && hbstrt_v2 >= last_recorded_diw_hpos) {
-                               cc = &curr_color_changes[next_color_change];
-                               cc->linepos = hbstrt_v2;
-                               cc->regno = RECORDED_REGISTER_CHANGE_OFFSET + 0x200;
-                               cc->value = 1;
-                               next_color_change++;
-                               cc[1].regno = -1;
+                               addcc(hbstrt_v2, RECORDED_REGISTER_CHANGE_OFFSET + 0x200, 1);
                                hblank_reset(hbstrt_v2);
                                exthblank_state = true;
-                               last_recorded_diw_hpos = cc->linepos;
-                               last_hblank_start = cc->linepos;
+                               last_hblank_start = hbstrt_v2;
                                if (debug_dma) {
-                                       record_dma_event(DMA_EVENT_HBS, diw_to_hpos(cc->linepos), vpos);
+                                       record_dma_event(DMA_EVENT_HBS, diw_to_hpos(hbstrt_v2), vpos);
                                }
                        }
                }
        }
 
+       // inject hsync and end in color changes (ultra mode debug)
+       if (hsyncdebug) {
+               syncdebugmarkers(pos);
+       }
+
        if (regno != 0xffff) {
-               cc = &curr_color_changes[next_color_change];
-               cc->linepos = pos;
-               cc->regno = regno;
-               cc->value = value;
-               next_color_change++;
-               cc[1].regno = -1;
+               addcc(pos, regno, value);
        }
 
        if (pos > last_recorded_diw_hpos) {
                last_recorded_diw_hpos = pos;
        }
 
+       int cchanges = next_color_change - start_color_change;
+       if (cchanges > 1 && hsyncdebug) {
+               if (cchanges == 2) {
+                       color_change *cc1 = &curr_color_changes[start_color_change];
+                       color_change *cc2 = &curr_color_changes[start_color_change + 1];
+                       if (cc1->linepos > cc2->linepos) {
+                               color_change cc = *cc2;
+                               *cc2 = *cc1;
+                               *cc1 = cc;
+                       }
+               } else {
+                       // debug only, can be slow
+                       for (int i = 0; i < cchanges; i++) {
+                               color_change *cc1 = &curr_color_changes[start_color_change + i];
+                               for(int j = i + 1; j < cchanges; j++) {
+                                       color_change *cc2 = &curr_color_changes[start_color_change + j];
+                                       if (cc1->linepos > cc2->linepos) {
+                                               color_change cc = *cc2;
+                                               *cc2 = *cc1;
+                                               *cc1 = cc;
+                                       }
+                               }
+                       }
+                       color_change *cc1 = &curr_color_changes[start_color_change];
+                       color_change *cc2 = &curr_color_changes[start_color_change];
+               }
+       }
+
 }
 
 static void sync_color_changes(int hpos)
@@ -1947,6 +2008,10 @@ static void update_mirrors(void)
                sprite_sprctlmask = 0x01;
        }
        set_chipset_mode();
+       hsyncdebug = 0;
+       if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
+               hsyncdebug = currprefs.gfx_overscanmode - OVERSCANMODE_ULTRA + 1;
+       }
 }
 
 extern struct color_entry colors_for_drawing;
@@ -5679,13 +5744,15 @@ static void reset_decisions_hsync_start(void)
                        }
                }
        }
-
-       if (!ecs_denise && vb_end_line) {
-               thisline_decision.vb = VB_NOVB;
-       }
 #endif
-       if (currprefs.gfx_overscanmode == OVERSCANMODE_ULTRA) {
-               thisline_decision.vb = VB_NOVB;
+
+       if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
+               if (thisline_decision.vb != VB_NOVB) {
+                       thisline_decision.vb = VB_VB | VB_NOVB;
+               }
+               if (vs_state_on) {
+                       thisline_decision.vb |= VB_VS;
+               }
        }
        if (nosignal_status == 1) {
                thisline_decision.vb = VB_XBLANK;
@@ -5990,8 +6057,14 @@ static void set_hcenter(void)
                if (hcenter_v2_end >= maxhpos << CCK_SHRES_SHIFT) {
                        hcenter_v2_end -= maxhpos << CCK_SHRES_SHIFT;
                }
+               hcenter_active = true;
        } else {
-               hcenter_v2 = 0;
+               if (beamcon0 & bemcon0_vsync_mask) {
+                       hcenter_v2 = (hcenter & 0xff) << CCK_SHRES_SHIFT;
+               } else {
+                       hcenter_v2 = 132 << CCK_SHRES_SHIFT;
+               }
+               hcenter_active = false;
        }
 }
 
@@ -6051,6 +6124,13 @@ static void updateextblk(void)
                exthblank = (bplcon0 & 1) && (bplcon3 & 1);
        }
 
+       if (!exthblank) {
+               hbstrt_v2 = (8 << CCK_SHRES_SHIFT) - 3;
+               hbstop_v2 = (47 << CCK_SHRES_SHIFT) - 7;
+               hbstrt_v2 = adjust_hr(hbstrt_v2);
+               hbstop_v2 = adjust_hr(hbstop_v2);
+       }
+
        if (new_beamcon0 & bemcon0_hsync_mask) {
 
                hsyncstartpos = hsstrt + 2;
@@ -6076,6 +6156,9 @@ static void updateextblk(void)
                        hsyncstartpos_start = REFRESH_FIRST_HPOS + 1;
                }
 
+               hsstrt_v2 = (hsstrt & 0xff) << CCK_SHRES_SHIFT;
+               hsstop_v2 = (hsstop & 0xff) << CCK_SHRES_SHIFT;
+
        } else {
 
                hsyncstartpos_start = hsyncstartpos_start_hw;
@@ -6083,8 +6166,14 @@ static void updateextblk(void)
                denisehtotal = 227 + 7;
                hsstop_detect2 = (35 + 9) * 2;
 
+               hsstrt_v2 = 18 << CCK_SHRES_SHIFT;
+               hsstop_v2 = 35 << CCK_SHRES_SHIFT;
+
        }
 
+       hsstrt_v2 = adjust_hr(hsstrt_v2);
+       hsstop_v2 = adjust_hr(hsstop_v2);
+
        // Out of range left. Denise/Lisa hcounter starts from 2 (skips first 2 lores pixels)
        if (hbstrt_v2 < (1 << CCK_SHRES_SHIFT)) {
                hbstrt_v2 = 0xffff;
@@ -6146,7 +6235,7 @@ static void updateextblk(void)
        denisehtotal <<= CCK_SHRES_SHIFT;
 
        // ECS Denise has 1 extra lores pixel in right border
-       if (currprefs.gfx_overscanmode == OVERSCANMODE_ULTRA) {
+       if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
                denisehtotal += 2 << (CCK_SHRES_SHIFT - 1);
        } else if (ecs_denise) {
                denisehtotal += 1 << (CCK_SHRES_SHIFT - 1);
@@ -6510,8 +6599,11 @@ static void init_hz(bool checkvposw)
                // assume VGA-like monitor if VARBEAMEN
                if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
                        maxhpos_display = maxhpos;
-                       hsstop_detect = 8 * 2;
-                       maxvpos_display_vsync += 2;
+                       hsstop_detect = hsstrt * 2;
+                       if (hsstop_detect > maxhpos / 2 * 2 || hsstop_detect < 4 * 2) {
+                               hsstop_detect = 4 * 2;
+                       }
+                       minfirstline = 0;
                } else {
                        int hp2 = maxhpos * 2;
                        if (exthblank) {
@@ -6591,7 +6683,7 @@ static void init_hz(bool checkvposw)
                                hsstop_detect += 7;
                        } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
                                hsstop_detect += 5;
-                       } else if (currprefs.gfx_overscanmode == OVERSCANMODE_ULTRA) {
+                       } else if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
                                maxhpos_display += EXTRAWIDTH_ULTRA;
                                maxvpos_display_vsync += 2;
                                minfirstline = 0;
@@ -6599,10 +6691,10 @@ static void init_hz(bool checkvposw)
                        }
                } else {
 
-                       if (currprefs.gfx_overscanmode == OVERSCANMODE_ULTRA) {
+                       if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
                                maxhpos_display += EXTRAWIDTH_ULTRA;
                                maxvpos_display_vsync += 2;
-                               hsstop_detect = 16;
+                               hsstop_detect = 18 * 2;
                                minfirstline = 0;
                        }
                }
@@ -6633,11 +6725,14 @@ static void init_hz(bool checkvposw)
        if (hsstop_detect < 0) {
                hsstop_detect = 0;
        }
+       if (minfirstline < 0) {
+               minfirstline = 0;
+       }
 
        vblank_extraline = !currprefs.cs_dipagnus && !ecs_denise ? 1 : 0;
 
        int minfirstline_hw = minfirstline;
-       if (currprefs.gfx_overscanmode == OVERSCANMODE_ULTRA) {
+       if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
                minfirstline = 0;
                minfirstline_hw = 0;
        } else if (currprefs.gfx_overscanmode == OVERSCANMODE_EXTREME) {
@@ -6711,8 +6806,8 @@ static void init_hz(bool checkvposw)
                maxvpos_display_vsync = 0;
        }
 
-       if (minfirstline < 1) {
-               minfirstline = 1;
+       if (minfirstline < vsync_startline) {
+               minfirstline = vsync_startline;
        }
 
        if (minfirstline >= maxvpos) {
@@ -6734,9 +6829,14 @@ static void init_hz(bool checkvposw)
                if (maxvpos_display_vsync < 0) {
                        maxvpos_display_vsync = 0;
                }
-               if (minfirstline <= vsync_startline) {
+               if (minfirstline < vsync_startline) {
                        minfirstline = vsync_startline;
                }
+               if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
+                       if (minfirstline > vsstrt + 1) {
+                               minfirstline = vsstrt + 1;
+                       }
+               }
        }
 
        if (beamcon0 & BEAMCON0_VARBEAMEN) {
@@ -11980,7 +12080,18 @@ static void hsync_handlerh(bool onvsync)
        hpos_hsync_extra = 0;
        estimate_last_fetch_cycle(hpos);
 
-       if (vb_end_next_line && !ecs_denise && currprefs.gfx_overscanmode < OVERSCANMODE_ULTRA) {
+       if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
+               if (beamcon0 & BEAMCON0_PAL) {
+                       if (vs_state_on_old && !vs_state_on_old2 && !lof_display) {
+                               record_color_change2(hpos, RECORDED_REGISTER_CHANGE_OFFSET + 0x206, 1);
+                       }
+               } else {
+                       if (vs_state_on_old && !vs_state_on_old2 && lof_display) {
+                               record_color_change2(hpos, RECORDED_REGISTER_CHANGE_OFFSET + 0x206, 1);
+                       }
+               }
+       }
+       if (vb_end_next_line && !ecs_denise) {
                record_color_change2(hpos, 0, COLOR_CHANGE_BLANK | 1);
        }
 
@@ -13003,18 +13114,20 @@ static void hsync_handler_post(bool onvsync)
                if (vpos == 3 && lof_store) {
                        vs_state_hw = true;
                }
-               if (vpos == 5) {
+               if (vpos == 5 + 1) {
                        vs_state_hw = false;
                }
        } else {
                if (vpos == 3) {
                        vs_state_hw = true;
                }
-               if (vpos == 6) {
+               if (vpos == 6 + 1) {
                        vs_state_hw = false;
                }
        }
 
+       vs_state_on_old2 = vs_state_on_old;
+       vs_state_on_old = vs_state_on;
        if (new_beamcon0 & bemcon0_vsync_mask) {
                vs_state_on = vs_state;
        } else {
@@ -13388,6 +13501,7 @@ void custom_reset(bool hardreset, bool keyboardreset)
        hbstrt_v2 = 0;
        hbstop_v2 = 0;
        hcenter_v2 = 0;
+       hcenter_active = false;
        set_hcenter();
        display_reset = 1;
        copper_bad_cycle = 0;
index 522a7d8f5dd0a7851d4d2f8fa44222962a8c0fe0..f2ba63a93496e306e623431b3dba37dc4bbeeb1c 100644 (file)
@@ -255,8 +255,11 @@ static int visible_top_start, visible_bottom_stop;
 static int vblank_top_start, vblank_bottom_stop;
 static int hblank_left_start, hblank_right_stop;
 static int hblank_left_start_hard, hblank_right_stop_hard;
-static bool exthblank, extborder, exthblanken, exthblankon;
+static bool extborder, exthblanken, exthblankon;
+static int exthblank;
+static int exthblank_set;
 static bool ehb_enable;
+static bool syncdebug;
 
 static int linetoscr_x_adjust_pixbytes, linetoscr_x_adjust_pixels;
 static int thisframe_y_adjust;
@@ -289,6 +292,8 @@ static bool aga_genlock_features_zdclken;
 static int hsync_shift_hack;
 static bool sprite_smaller_than_64, sprite_smaller_than_64_inuse;
 static bool full_blank;
+static bool hsync_debug, vsync_debug, hblank_debug, vblank_debug;
+static int hcenter_debug;
 static uae_u8 vb_state;
 
 uae_sem_t gui_sem;
@@ -480,16 +485,18 @@ static void reset_custom_limits(void)
 static void expand_vb_state(void)
 {
        full_blank = vb_state == VB_PRGVB || (vb_state >= VB_XBLANK && vb_state < VB_XBORDER) || (vb_state == VB_XBORDER);
+       vsync_debug = (vb_state & VB_VS) != 0;
+       vblank_debug = (vb_state & VB_VB) != 0;
 }
 
 static void extblankcheck(void)
 {
        exthblankon = dp_for_drawing && (dp_for_drawing->bplcon3 & 1) && (dp_for_drawing->bplcon0 & 1);
        if (exthblanken && exthblankon) {
-               exthblank = true;
+               exthblank = exthblank_set;
        }
        if (exthblanken && !exthblankon) {
-               exthblank = false;
+               exthblank = 0;
        }
 }
 
@@ -553,7 +560,7 @@ static void set_vblanking_limits(void)
                vblank_bottom_stop = visible_bottom_stop;
        }
 
-       if (currprefs.gfx_overscanmode == OVERSCANMODE_ULTRA) {
+       if (syncdebug) {
                return;
        }
 
@@ -596,7 +603,7 @@ int get_vertical_visible_height(bool useoldsize)
        if (interlace_seen && currprefs.gfx_vresolution > 0) {
                h -= 1 << (currprefs.gfx_vresolution - 1);
        }
-       if (currprefs.gfx_overscanmode < OVERSCANMODE_ULTRA) {
+       if (syncdebug) {
                bool hardwired = true;
                if (ecs_agnus) {
                        hardwired = (new_beamcon0 & BEAMCON0_VARVBEN) == 0;
@@ -614,7 +621,7 @@ int get_vertical_visible_height(bool useoldsize)
 
 static void set_hblanking_limits(void)
 {
-       if (currprefs.gfx_overscanmode == OVERSCANMODE_ULTRA) {
+       if (syncdebug) {
                hblank_left_start_hard = visible_left_start;
                hblank_right_stop_hard = visible_right_stop;
                return;
@@ -654,6 +661,8 @@ static void set_hblanking_limits(void)
        } else if (currprefs.gfx_overscanmode == OVERSCANMODE_BROADCAST) {
                hbstrt = (239 << CCK_SHRES_SHIFT) - 3;
                doblank = true;
+       } else if (currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA) {
+               doblank = true;
        }
 
        if (doblank && programmedmode != 1) {
@@ -1102,7 +1111,7 @@ static xcolnr getbgc(int blank)
        //return colors_for_drawing.acolors[0];
        return xcolors[0xf0f];
 #endif
-       if (exthblank) {
+       if (exthblank > 0) {
                return fullblack;
        }
        bool extblken = ce_is_extblankset(colors_for_drawing.extra);
@@ -1541,6 +1550,84 @@ static void pfield_do_fill_line (int start, int stop, int blank)
        }
 }
 
+static void pfield_do_darken_line(int start, int stop, int vp)
+{
+       struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo;
+       if (stop <= start)
+               return;
+       if (currprefs.gfx_resolution) {
+               vp >>= 1;
+       }
+       bool brd = !vsync_debug && !hsync_debug && !vblank_debug && !hblank_debug && !hcenter_debug && ce_is_borderblank(colors_for_drawing.extra);
+       bool vs = vsync_debug;
+       if (hcenter_debug) {
+               vs = false;
+
+       }
+       int c0 = 0x000;
+       int c1 = 0x136;
+       int c2 = 0x686;
+       bool csync = currprefs.gfx_overscanmode == OVERSCANMODE_ULTRA + 2;
+       bool trans = currprefs.gfx_overscanmode == OVERSCANMODE_ULTRA;
+       if (!csync) {
+               bool sync = hsync_debug || vs;
+               if (sync && currprefs.gfx_overscanmode > OVERSCANMODE_ULTRA) {
+                       c0 = 0x831;
+                       c1 = 0x000;
+               }
+               if (hcenter_debug && vsync_debug && currprefs.gfx_overscanmode > OVERSCANMODE_ULTRA) {
+                       c0 = 0x381;
+               }
+       } else {
+               if (hsync_debug) {
+                       c0 = 0x831;
+                       c1 = 0x000;
+               }
+       }
+       if (!trans) {
+               vp = 0;
+               if (!c0) {
+                       c0 = c1;
+               } else {
+                       c1 = c0;
+               }
+       }
+       if (vidinfo->drawbuffer.pixbytes == 4) {
+               uae_u32 *b = (uae_u32 *)xlinebuffer;
+               for (int i = start; i < stop; i++) {
+                       int s = (i ^ vp) & 3;
+                       if (brd) {
+                               if (playfield_start_pre >= playfield_start && (i < playfield_start || i >= playfield_end)) {
+                                       if (s == 1) {
+                                               b[i] = xcolors[c2];
+                                       } else if (s == 3) {
+                                               b[i] = xcolors[c1];
+                                       }
+                               } else if (i < playfield_start_pre || i >= playfield_end_pre) {
+                                       if (s == 1) {
+                                               b[i] = xcolors[c2];
+                                       } else if (s == 3) {
+                                               b[i] = xcolors[c1];
+                                       }
+                               }
+                       } else {
+                               if (s == 1) {
+                                       b[i] = xcolors[c0];
+                               } else if (s == 3) {
+                                       b[i] = xcolors[c1];
+                               }
+                               if (!trans) {
+                                       if (s == 0) {
+                                               b[i] = xcolors[c0];
+                                       } else if (s == 2) {
+                                               b[i] = xcolors[c1];
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
 static void fill_line2(int startpos, int len)
 {
        struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo;
@@ -1603,6 +1690,9 @@ static void fill_line_border(int lineno)
                int b = hposblank;
                hposblank = 3;
                fill_line2(lastpos, w);
+               if (syncdebug) {
+                       pfield_do_darken_line(lastpos, endpos, lineno);
+               }
                if (need_genlock_data) {
                        memset(xlinebuffer_genlock + lastpos, get_genlock_transparency_border(), w);
                }
@@ -1614,11 +1704,15 @@ static void fill_line_border(int lineno)
        if (hposblank) {
                hposblank = 3;
                fill_line2(lastpos, w);
+               if (syncdebug) {
+                       pfield_do_darken_line(lastpos, endpos, lineno);
+               }
                if (need_genlock_data) {
                        memset(xlinebuffer_genlock + lastpos, get_genlock_transparency_border(), w);
                }
                return;
        }
+
        // hblank not visible
        if (hblank_left <= lastpos && hblank_right >= endpos) {
                fill_line2(lastpos, w);
@@ -2103,7 +2197,7 @@ static void pfield_do_linetoscr_spr(int start, int stop, int blank)
                bool bb = ce_is_borderblank(colors_for_drawing.extra);
 #endif
                pixel = pfield_do_linetoscr_sprite(src_pixel, start, stop);
-               pfield_do_fill_line(start, stop, bb || exthblank);
+               pfield_do_fill_line(start, stop, bb || exthblank > 0);
        } else {
                pixel = pfield_do_linetoscr_sprite(src_pixel, start, stop);
                if (exthblank) {
@@ -2491,7 +2585,7 @@ static void pfield_set_linetoscr (void)
 // A1000 Denise right border bug: sprites have 1 extra lores pixel visible
 static void pfield_do_linetoscr_bordersprite_a1000(int start, int stop, int blank)
 {
-       if (blank || exthblank || extborder) {
+       if (blank || exthblank > 0 || extborder) {
                pfield_do_fill_line(start, stop, blank);
                return;
        }
@@ -2511,7 +2605,7 @@ static void pfield_do_linetoscr_bordersprite_a1000(int start, int stop, int blan
 // left or right AGA border sprite
 static void pfield_do_linetoscr_bordersprite_aga(int start, int stop, int blank)
 {
-       if (blank || exthblank || extborder) {
+       if (blank || exthblank > 0 || extborder) {
                pfield_do_fill_line(start, stop, blank);
                return;
        }
@@ -3407,19 +3501,26 @@ static void pfield_expand_dp_bplconx (int regno, int v, int hp, int vp)
                break;
        case 0x200: // hblank
                if (v) {
-                       if (currprefs.gfx_overscanmode < OVERSCANMODE_ULTRA) {
-                               exthblanken = true;
-                       }
+                       exthblanken = true;
                        if (vp >= 0) {
                                extblankcheck();
                        } else {
-                               exthblank = true;
+                               exthblank = exthblank_set;
                        }
                } else {
                        exthblanken = false;
-                       exthblank = false;
+                       exthblank = 0;
                }
                return;
+       case 0x202: // hsync (debug)
+               hsync_debug = v;
+               return;
+       case 0x204: // hblank (debug)
+               hblank_debug = v;
+               return;
+       case 0x206: // hcenter (denug)
+               hcenter_debug = v;
+               return;
 #endif
        }
        pfield_expand_dp_bplcon();
@@ -3494,18 +3595,19 @@ static void playfield_hard_way(line_draw_func worker_pfield, int first, int last
 static void do_color_changes(line_draw_func worker_border, line_draw_func worker_pfield, int vp)
 {
        struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo;
-       int i;
        int lastpos = visible_left_border;
+       int lastpos2 = lastpos;
        int endpos = visible_left_border + vidinfo->drawbuffer.inwidth;
        bool vbarea = vp < vblank_top_start || vp >= vblank_bottom_stop;
 
        extborder = false; // reset here because it always have start and end in same scanline
+       hcenter_debug = 0;
        if (!ecs_denise) {
                // used for OCS Denise blanking bug when not ECS Denise or AGA.
-               exthblank = false;
+               exthblank = 0;
        }
        ehb_enable = true;
-       for (i = dip_for_drawing->first_color_change; i <= dip_for_drawing->last_color_change; i++) {
+       for (int 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;
                int nextpos, nextpos_in_range;
@@ -3517,7 +3619,7 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker
                }
 
                nextpos_in_range = nextpos;
-               if (nextpos > endpos) {
+               if (nextpos_in_range > endpos) {
                        nextpos_in_range = endpos;
                }
 
@@ -3618,6 +3720,15 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker
                                        lastpos = nextpos_in_range;
                                }
                        }
+
+                       if (syncdebug) {
+                               if (hblank_debug || vblank_debug || hsync_debug || vsync_debug || hcenter_debug || exthblank || ce_is_borderblank(colors_for_drawing.extra)) {
+                                       pfield_do_darken_line(lastpos2, nextpos_in_range, vp);
+                               }
+                               if (nextpos_in_range > lastpos2) {
+                                       lastpos2 = nextpos_in_range;
+                               }
+                       }
                }
 
                if (i < dip_for_drawing->last_color_change) {
@@ -3635,9 +3746,12 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker
                                        }
                                } else if (value & COLOR_CHANGE_BLANK) {
                                        if (value & 1) {
-                                               exthblank = true;
+                                               exthblank = exthblank_set;
                                        } else {
-                                               exthblank = false;
+                                               exthblank = 0;
+                                               // so that OCS Denise blanking bug is marked in debug mode
+                                               hblank_debug = false;
+                                               vblank_debug = false;
                                        }
                                } else if (value & COLOR_CHANGE_BRDBLANK) {
                                        colors_for_drawing.extra &= ~(1 << CE_BORDERBLANK);
@@ -3659,6 +3773,7 @@ static void do_color_changes(line_draw_func worker_border, line_draw_func worker
                        }
                }
        }
+
        if (vp >= 0 && hsync_shift_hack > 0) {
                // hpos shift hack
                int shift = (hsync_shift_hack << lores_shift) * vidinfo->drawbuffer.pixbytes;
@@ -3867,7 +3982,7 @@ static void pfield_draw_line(struct vidbuffer *vb, int lineno, int gfx_ypos, int
                        pfield_erase_vborder_sprites();
                }
 #endif
-               if (!dosprites && !have_color_changes) {
+               if (!syncdebug && !dosprites && !have_color_changes) {
                        if (dp_for_drawing->plfleft < -1) {
                                // blanked border line
                                int tmp = hposblank;
@@ -5187,14 +5302,18 @@ void reset_drawing(void)
        struct amigadisplay *ad = &adisplays[monid];
        struct vidbuf_description *vidinfo = &ad->gfxvidinfo;
 
+       syncdebug = currprefs.gfx_overscanmode >= OVERSCANMODE_ULTRA;
        max_diwstop = 0;
        vb_state = 0;
-       exthblank = false;
+       exthblank = 0;
+       exthblank_set = syncdebug ? -1 : 1;
        exthblanken = false;
        exthblankon = false;
        extborder = false;
        display_reset = 1;
        ehb_enable = true;
+       hblank_debug = vblank_debug = hsync_debug = vsync_debug = false;
+       hcenter_debug = 0;
 
        lores_reset ();
 
index c303a8e5ada995e3ce5e9d30343b88bd38711ae8..9738be8f4c4e22c7863661bf18239d63b3750306 100644 (file)
@@ -142,6 +142,8 @@ STATIC_INLINE bool ce_is_borderntrans(uae_u16 data)
        return (data & (1 << CE_BORDERNTRANS)) != 0;
 }
 
+#define VB_VB 0x20 // vblank
+#define VB_VS 0x10 // vsync
 #define VB_XBORDER 0x08 // forced border color or bblank
 #define VB_XBLANK 0x04 // forced bblank
 #define VB_PRGVB 0x02 // programmed vblank
index af9cde7330cb31aea40a9ae11e740eec62164a6a..d4740013766ac8101c18691c6d3895eae564e8f8 100644 (file)
 #define IDC_SETTINGSTEXT3               1520
 #define IDC_DISPLAY_VARSYNC             1520
 #define IDC_ECS_AGNUS                   1521
-#define IDC_DISPLAY_VARSYNC2            1521
 #define IDC_DISPLAY_RESIZE              1521
 #define IDC_ECS_DENISE                  1522
 #define IDC_ECS                         1523
index 14788ec794149afcee3f10e47ef5660804e61384..d66b43ecb662660870da1f5a6e83ebcab645a5a9 100644 (file)
@@ -8473,6 +8473,8 @@ static void values_to_displaydlg (HWND hDlg)
        xSendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("Overscan+"));
        xSendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("Extreme"));
        xSendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("Ultra extreme debug"));
+       xSendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("Ultra extreme debug (HV)"));
+       xSendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_ADDSTRING, 0, (LPARAM)_T("Ultra extreme debug (C)"));
        xSendDlgItemMessage(hDlg, IDC_OVERSCANMODE, CB_SETCURSEL, workprefs.gfx_overscanmode, 0);
 
        xSendDlgItemMessage(hDlg, IDC_AUTORESOLUTIONSELECT, CB_RESETCONTENT, 0, 0);