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();
}
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)
_T("compforcesettings"),
_T("comp_catchdetect"),
+ _T("hblank_glitch"),
+
NULL
};
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]]);
|| 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)
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;
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;
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
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;
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;
{
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;
}
}
- 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);
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
}
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)
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 {
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;
}
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;
} else {
maxvpos_display_vsync = 3;
minfirstline -= eh / 2;
- if (minfirstline < 8) {
- minfirstline = 8;
- }
}
}
if (minfirstline < 1) {
minfirstline = 1;
}
- if (!(beamcon0 & 0x80) && minfirstline < 8 && !eh) {
- minfirstline = 8;
- }
if (minfirstline >= maxvpos) {
minfirstline = maxvpos - 1;
}
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;
compute_framesync();
devices_syncchange();
+ display_reset = 2;
#ifdef PICASSO96
init_hz_p96(0);
// 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;
#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
}
}
+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;
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) {
#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++;
serial_rbf_clear();
}
- if ((v & 0x8000) && old != v) {
+ if (old != v) {
doint_delay();
}
return true;
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)
return;
}
if (!aga_mode) {
- v &= ~(0x0008 | 0x0010 | 0x1000 | 0x0800);
+ v &= ~(0x0010 | 0x1000);
}
v &= ~(0x8000 | 0x4000 | 0x0080 | 0x0040);
if (diwhigh_written && diwhigh == v) {
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;
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;
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
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();
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.
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) {
}
// 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];
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();
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);
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();
}
nextline_how = nln_normal;
- vsync_handle_check();
//checklacecount (bplcon0_interlace_seen || lof_lace);
}
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--;
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();
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;
}
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);
}
}
// 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) {
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;
vs_state_hw = false;
}
}
+
if (new_beamcon0 & (0x0200 | 0x0010)) {
vs_state_on = vs_state;
} else {
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;
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;
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;
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;
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;
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();
return;
}
- if (!lockscr(vb, false, true)) {
+ if (!lockscr(vb, false, true, display_reset > 0)) {
notice_screen_contents_lost(monid);
return;
}
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 {
vidinfo->drawbuffer.tempbufferinuse = true;
}
- unlockscr(vb, -1, -1);
+ unlockscr(vb, display_reset ? -2 : -1, -1);
}
void check_prefs_picasso(void)
exthblank = false;
exthblanken = false;
extborder = false;
+ display_reset = 1;
lores_reset ();
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
int cs_hacks;
int cs_ciatype[2];
int cs_kbhandshake;
- bool cs_ocshblankbug;
struct boardromconfig expansionboard[MAX_EXPANSION_BOARDS];
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);
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;
volatile bool fakemode;
uae_u8 *fakebitmap;
+ int fakelock;
uae_thread_id fakemodetid;
D3DXMATRIXA16 m_matProj, m_matProj2, m_matProj_out;
{
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) {
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];
{
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);
{
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;
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);
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);
}
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;
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) {
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;
D3D_unlocktexture(monid, -1, -1);
return NULL;
}
- d3d->fulllocked = fullupdate;
+ d3d->fulllocked = fullupdate > 0;
*pitch = lock.Pitch;
if (height)
*height = d3d->tin_h;
if (d3d->fakemode)
return true;
- if (!isd3d (d3d) || !d3d->texture)
+ if (!isd3d (d3d) || !d3d->texture1 || !d3d->texture2)
return false;
if (d3d->filenotificationhandle != NULL) {
}
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;
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);
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);
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);
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];
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;
#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
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
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 {
}
}
-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;
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();
{
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);
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]);
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);
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);