}
}
+static void blitter_doit (void)
+{
+ #ifdef BLITTER_DEBUG
+ if (!blitter_dontdo)
+ actually_do_blit ();
+ else
+ bltstate = BLT_done;
+#else
+ actually_do_blit ();
+#endif
+ blitter_done (current_hpos ());
+}
+
void blitter_handler (uae_u32 data)
{
static int blitter_stuck;
blit_slowdown = -1;
return;
}
-#ifdef BLITTER_DEBUG
- if (!blitter_dontdo)
- actually_do_blit ();
- else
- bltstate = BLT_done;
-#else
- actually_do_blit ();
-#endif
- blitter_done (current_hpos ());
+ blitter_doit ();
}
#ifdef CPUEMU_12
}
blt_info.got_cycle = 1;
- if (currprefs.immediate_blits)
- cycles = 1;
-
blit_waitcyclecounter = 0;
- blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1));
- event2_newevent (ev2_blitter, blit_cyclecounter, 0);
+
+ if (currprefs.immediate_blits) {
+ blitter_doit ();
+ } else {
+ blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1));
+ event2_newevent (ev2_blitter, blit_cyclecounter, 0);
+ }
}
void do_blitter (int hpos, int copper)
while (bltstate != BLT_done && dmaen (DMA_BLITTER)) {
x_do_cycles (8 * CYCLE_UNIT);
}
+ if (bltstate == BLT_done)
+ return;
}
if (warned && dmaen (DMA_BLITTER) && blt_info.got_cycle) {
cfgfile_write (f, L"gfx_height_windowed", L"%d", p->gfx_size_win.height);
cfgfile_write (f, L"gfx_width_fullscreen", L"%d", p->gfx_size_fs.width);
cfgfile_write (f, L"gfx_height_fullscreen", L"%d", p->gfx_size_fs.height);
- cfgfile_write (f, L"gfx_refreshrate", L"%d", p->gfx_refreshrate);
+ cfgfile_write (f, L"gfx_refreshrate", L"%d", p->gfx_apmode[0].gfx_refreshrate);
+ cfgfile_dwrite (f, L"gfx_refreshrate_rtg", L"%d", p->gfx_apmode[1].gfx_refreshrate);
cfgfile_write_bool (f, L"gfx_autoresolution", p->gfx_autoresolution);
cfgfile_dwrite (f, L"gfx_autoresolution_min_vertical", vertmode[p->gfx_autoresolution_minv + 1]);
cfgfile_dwrite (f, L"gfx_autoresolution_min_horizontal", horizmode[p->gfx_autoresolution_minh + 1]);
|| cfgfile_intval (option, value, L"gfx_left_windowed", &p->gfx_size_win.y, 1)
|| cfgfile_intval (option, value, L"gfx_width_fullscreen", &p->gfx_size_fs.width, 1)
|| cfgfile_intval (option, value, L"gfx_height_fullscreen", &p->gfx_size_fs.height, 1)
- || cfgfile_intval (option, value, L"gfx_refreshrate", &p->gfx_refreshrate, 1)
+ || cfgfile_intval (option, value, L"gfx_refreshrate", &p->gfx_apmode[0].gfx_refreshrate, 1)
+ || cfgfile_intval (option, value, L"gfx_refreshrate_rtg", &p->gfx_apmode[1].gfx_refreshrate, 1)
|| cfgfile_yesno (option, value, L"gfx_autoresolution", &p->gfx_autoresolution)
|| cfgfile_intval (option, value, L"gfx_backbuffers", &p->gfx_apmode[0].gfx_backbuffers, 1)
|| cfgfile_intval (option, value, L"gfx_backbuffers_rtg", &p->gfx_apmode[1].gfx_backbuffers, 1)
#define CIAB_DEBUG_R 0
#define CIAB_DEBUG_W 0
#define DONGLE_DEBUG 0
+#define KB_DEBUG 0
#define TOD_HACK
static unsigned int ciaapra, ciaaprb, ciaadra, ciaadrb, ciaasdr, ciaasdr_cnt;
static unsigned int ciabprb, ciabdra, ciabdrb, ciabsdr, ciabsdr_cnt;
static int div10;
-#define KBACK_WAIT 1
-#define KBACK_ACTIVE 2
-#define KBACK_GOT 3
-static int kbstate, kback;
+static int kbstate, kblostsynccnt;
+static uae_u8 kbcode;
static uae_u8 serbits;
static int warned = 10;
static void setcode (uae_u8 keycode)
{
- ciaasdr = ~((keycode << 1) | (keycode >> 7));
+ kbcode = ~((keycode << 1) | (keycode >> 7));
}
static void sendrw (void)
{
setcode (AK_RESETWARNING);
- kback = KBACK_WAIT;
+ kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits.
ciaaicr |= 8;
RethinkICRA ();
write_log (L"KB: sent reset warning code (phase=%d)\n", resetwarning_phase);
if (resetwarning_timer <= 0) {
write_log (L"KB: reset warning forced reset. Phase=%d\n", resetwarning_phase);
resetwarning_phase = -1;
- kback = 0;
+ kblostsynccnt = 0;
uae_reset (0);
}
}
if (resetwarning_phase == 1) {
- if (kback == KBACK_GOT) { /* first AK_RESETWARNING handshake received */
+ if (!kblostsynccnt) { /* first AK_RESETWARNING handshake received */
write_log (L"KB: reset warning second phase..\n");
resetwarning_phase = 2;
resetwarning_timer = maxvpos_nom * 5;
sendrw ();
}
} else if (resetwarning_phase == 2) {
- if (kback >= KBACK_ACTIVE) { /* second AK_RESETWARNING handshake active */
+ if (ciaacra & 0x40) { /* second AK_RESETWARNING handshake active */
resetwarning_phase = 3;
write_log (L"KB: reset warning SP = output\n");
/* System won't reset until handshake signal becomes inactive or 10s has passed */
resetwarning_timer = 10 * maxvpos_nom * vblank_hz;
}
} else if (resetwarning_phase == 3) {
- if (kback != KBACK_ACTIVE) { /* second AK_RESETWARNING handshake disabled */
+ if (!(ciaacra & 0x40)) { /* second AK_RESETWARNING handshake disabled */
write_log (L"KB: reset warning end by software. reset.\n");
resetwarning_phase = -1;
- kback = 0;
+ kblostsynccnt = 0;
uae_reset (0);
}
}
{
}
+static void keyreq (void)
+{
+#if KB_DEBUG
+ write_log (L"code=%x\n", kbcode);
+#endif
+ ciaasdr = kbcode;
+ kblostsynccnt = 8 * maxvpos * 8; // 8 frames * 8 bits.
+ ciaaicr |= 8;
+ RethinkICRA ();
+}
+
void CIA_hsync_posthandler (bool dotod)
{
resetwarning_check ();
while (keys_available ())
get_next_key ();
- } else if ((keys_available () || kbstate < 3) && (kback == 0 || kback == KBACK_GOT) && (hsync_counter & 15) == 0) {
+ } else if ((keys_available () || kbstate < 3) && !kblostsynccnt && (hsync_counter & 15) == 0) {
switch (kbstate)
{
case 0:
- ciaasdr = 0; /* powerup resync */
+ kbcode = 0; /* powerup resync */
kbstate++;
break;
case 1:
kbstate++;
break;
case 3:
- ciaasdr = ~get_next_key ();
+ kbcode = ~get_next_key ();
break;
}
- kback = KBACK_WAIT;
- ciaaicr |= 8;
- RethinkICRA ();
+ keyreq ();
}
}
{
led_vsync ();
CIA_handler ();
+ if (kblostsynccnt > 0) {
+ kblostsynccnt -= maxvpos;
+ if (kblostsynccnt <= 0) {
+ kblostsynccnt = 0;
+ keyreq ();
+#if KB_DEBUG
+ write_log (L"lostsync\n");
+#endif
+ }
+ }
}
void CIA_vsync_posthandler (bool dotod)
case 12:
CIA_update ();
ciaasdr = val;
- if (ciaacra & 0x40) {
- kback = KBACK_ACTIVE;
- } else {
- if (kback == KBACK_ACTIVE)
- kback = KBACK_GOT;
- ciaasdr_cnt = 0;
- }
if ((ciaacra & 0x41) == 0x41 && ciaasdr_cnt == 0)
ciaasdr_cnt = 8 * 2;
CIA_calctimers ();
val &= 0x7f; /* bit 7 is unused */
if ((val & 1) && !(ciaacra & 1))
ciaastarta = CIASTARTCYCLESCRA;
- ciaacra = val;
- if (ciaacra & 0x40) {
- kback = KBACK_ACTIVE;
- } else if (kback == KBACK_ACTIVE) {
- kback = KBACK_GOT;
+ if ((val & 0x40) != (ciaacra & 0x40)) {
+ /* todo: check if low to high or high to low only */
+ kblostsynccnt = 0;
+#if KB_DEBUG
+ write_log (L"KB_ACK %02x->%02x\n", val, ciaacra);
+#endif
}
+ ciaacra = val;
if (ciaacra & 0x10) {
ciaacra &= ~0x10;
ciaata = ciaala;
tod_hack_enabled = 312 * 50 * 10;
#endif
- kback = 0;
+ kblostsynccnt = 0;
serbits = 0;
oldovl = 1;
oldcd32mute = 1;
if (dstptr)
dstbak = dst = dstptr;
else
- dstbak = dst = xmalloc (uae_u8, 4 + 4 + 1 + 1 + 1 + 1);
+ dstbak = dst = xmalloc (uae_u8, 4 + 4 + 1 + 1 + 1 + 1 + 1 + 2);
save_u32 (getcapslockstate () ? 1 : 0);
save_u32 (1);
save_u8 (kbstate);
save_u8 (0);
save_u8 (0);
- save_u8 (kback);
+ save_u8 (0);
+ save_u8 (kbcode);
+ save_u16 (kblostsynccnt);
*len = dst - dstbak;
return dstbak;
}
kbstate = restore_u8 ();
restore_u8 ();
restore_u8 ();
- kback = restore_u8 ();
+ restore_u8 ();
if (!(v & 1))
kbstate = 3;
+ kbcode = restore_u8 ();
+ kblostsynccnt = restore_u16 ();
return src;
}
/* Events */
-unsigned long int event_cycles, nextevent, is_lastline, currcycle;
-long cycles_to_next_event;
-long max_cycles_to_next_event;
-long cycles_to_hsync_event;
unsigned long int vsync_cycles;
static int extra_cycle;
-unsigned long start_cycles;
static int rpt_did_reset;
struct ev eventtab[ev_max];
struct ev2 eventtab2[ev2_max];
-volatile frame_time_t vsynctime, vsyncmintime;
-
int vpos;
static int vpos_count, vpos_count_prev;
static int lof_store; // real bit in custom registers
return;
rpt_did_reset = 1;
- is_lastline = 0;
- vsyncmintime = read_processor_time () + vsynctime;
+ is_syncline = 0;
+ vsyncmintime = read_processor_time () + vsynctimebase;
write_log (L"Resetting frame rate hack\n");
}
return linetoggle;
}
-int vsynctime_orig;
+int vsynctimebase_orig;
void compute_vsynctime (void)
{
if (!fake_vblank_hz)
fake_vblank_hz = vblank_hz;
if (currprefs.turbo_emulation)
- vsynctime = vsynctime_orig = 1;
+ vsynctimebase = vsynctimebase_orig = 1;
else
- vsynctime = vsynctime_orig = syncbase / fake_vblank_hz;
+ vsynctimebase = vsynctimebase_orig = syncbase / fake_vblank_hz;
#if 0
if (!picasso_on) {
updatedisplayarea ();
events_schedule();
}
-
-void MISC_handler (void)
-{
- static bool dorecheck;
- bool recheck;
- int i;
- evt mintime;
- evt ct = get_cycles ();
- static int recursive;
-
- if (recursive) {
- dorecheck = true;
- return;
- }
- recursive++;
- eventtab[ev_misc].active = 0;
- recheck = true;
- while (recheck) {
- recheck = false;
- mintime = ~0L;
- for (i = 0; i < ev2_max; i++) {
- if (eventtab2[i].active) {
- if (eventtab2[i].evtime == ct) {
- eventtab2[i].active = false;
- eventtab2[i].handler (eventtab2[i].data);
- if (dorecheck || eventtab2[i].active) {
- recheck = true;
- dorecheck = false;
- }
- } else {
- evt eventtime = eventtab2[i].evtime - ct;
- if (eventtime < mintime)
- mintime = eventtime;
- }
- }
- }
- }
- if (mintime != ~0L) {
- eventtab[ev_misc].active = true;
- eventtab[ev_misc].oldcycles = ct;
- eventtab[ev_misc].evtime = ct + mintime;
- events_schedule ();
- }
- recursive--;
-}
-
static int irq_nmi;
void NMI_delayed (void)
if (vs > 0) {
- vsyncmintime = vsynctime;
+ curr_time = read_processor_time ();
render_screen ();
show_screen ();
frame_shown = true;
- return;
} else if (vs < 0) {
if (!vblank_hz_state)
return;
- vsyncmintime = vsynctime;
-
if (vs == -2 || vs == -3) {
+
// fastest possible
- curr_time = vsync_busywait_end ();
- vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0);
curr_time = read_processor_time ();
- vsyncmintime = curr_time + vsynctime;
+ vsync_busywait_end ();
+ vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0);
vsync_busywait_start ();
+ vsyncmintime = curr_time;
+ vsyncmaxtime = curr_time + vsynctimebase;
} else {
bool show = show_screen_maybe (false);
vsync_busywait_do (&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0);
curr_time = read_processor_time ();
- vsyncmintime = curr_time + vsynctime;
+ vsyncmintime = curr_time + vsynctimebase;
if (!show) {
show_screen ();
if (extraframewait)
}
return;
}
+ if (currprefs.m68k_speed < 0) {
+ curr_time = read_processor_time ();
+ if (curr_time - vsyncmaxtime >= 0 && curr_time - vsyncmaxtime < vsynctimebase) {
+ vsyncmaxtime = curr_time + vsynctimebase - (curr_time - vsyncmaxtime);
+ } else {
+ vsyncmaxtime = curr_time + vsynctimebase;
+ }
+ vsyncmintime = curr_time;
+ return;
+ }
bool didrender = false;
if (!picasso_on)
curr_time = start = read_processor_time ();
while (rpt_vsync () < 0)
rtg_vsynccheck ();
- curr_time = read_processor_time ();
- vsyncmintime = curr_time + vsynctime;
idletime += read_processor_time() - start;
+ curr_time = read_processor_time ();
+ vsyncmintime = vsyncmaxtime = curr_time + vsynctimebase;
if (didrender)
show_screen ();
frame_shown = true;
frametime2 += last;
timeframes++;
if ((timeframes % mcnt) == 0) {
- double idle = 1000 - (idletime == 0 ? 0.0 : (double)idletime * 1000.0 / (vsynctime * mcnt));
+ double idle = 1000 - (idletime == 0 ? 0.0 : (double)idletime * 1000.0 / (vsynctimebase * mcnt));
int fps = frametime2 == 0 ? 0 : (syncbase * mcnt) / (frametime2 / 10);
if (fps > 9999)
fps = 9999;
vsync_rendered = false;
frame_shown = false;
- //write_log (L"%d %d %d\n", vsynctime, read_processor_time () - vsyncmintime, read_processor_time () - prevtime);
+ //write_log (L"%d %d %d\n", vsynctimebase, read_processor_time () - vsyncmintime, read_processor_time () - prevtime);
prevtime = read_processor_time ();
fpscounter ();
- if (!isvsync_chipset ()
-#ifdef AVIOUTPUT
- && ((avioutput_framelimiter && avioutput_enabled) || !avioutput_enabled)
-#endif
- ) {
-#ifdef JIT
- if (!currprefs.cachesize) {
-#endif
- if (currprefs.m68k_speed < 0) {
- frame_time_t curr_time = read_processor_time ();
- vsyncmintime += vsynctime;
- /* @@@ Mathias? How do you think we should do this? */
- /* If we are too far behind, or we just did a reset, adjust the
- * needed time. */
- if ((long int)(curr_time - vsyncmintime) > 0 || rpt_did_reset)
- vsyncmintime = curr_time + vsynctime;
- rpt_did_reset = 0;
- if (render_screen ())
- show_screen ();
- frame_shown = true;
- } else {
- framewait ();
- }
-#ifdef JIT
- } else {
- if (currprefs.m68k_speed == 0) {
- framewait ();
- } else {
- if (render_screen ())
- show_screen ();
- frame_shown = true;
- }
- }
-#endif
- } else {
- framewait ();
- }
+ framewait ();
#if CUSTOM_DEBUG > 1
if ((intreq & 0x0020) && (intena & 0x0020))
vsync_cycles = get_cycles ();
}
-#ifdef JIT
-
-#define N_LINES 8
-
-STATIC_INLINE int trigger_frh (int v)
-{
- return (v & (N_LINES - 1)) == 0;
-}
-
-static long int diff32 (frame_time_t x, frame_time_t y)
-{
- return (long int)(x - y);
-}
-static void frh_handler (void)
-{
- if (currprefs.m68k_speed < 0) {
- frame_time_t curr_time = read_processor_time ();
- vsyncmintime += vsynctime * N_LINES / maxvpos_nom;
- /* @@@ Mathias? How do you think we should do this? */
- /* If we are too far behind, or we just did a reset, adjust the
- * needed time. */
- if (rpt_did_reset) {
- vsyncmintime = curr_time + vsynctime;
- rpt_did_reset = 0;
- }
- /* Allow this to be one frame's worth of cycles out */
- while (diff32 (curr_time, vsyncmintime + vsynctime) > 0) {
- vsyncmintime += vsynctime * N_LINES / maxvpos_nom;
- if (currprefs.turbo_emulation || vblank_found_chipset || vblank_found_rtg)
- break;
- }
- }
-}
-#endif
-
static void copper_check (int n)
{
if (cop_state.state == COP_wait) {
events_dmal (7);
}
-static bool is_vsync (void)
+static bool is_custom_vsync (void)
{
int vp = vpos + 1;
int vpc = vpos_count + 1;
}
#endif
-
events_dmal_hsync ();
+ if (currprefs.m68k_speed < 0) {
+ if (vpos + 1 == maxvpos + lof_store) {
+ /* really last line, just run the cpu emulation until whole vsync time has been used */
+ is_syncline = 1;
+ vsyncmintime = vsyncmaxtime;
+ } else {
+ /* end of scanline, run cpu emulation as long as we still have time */
+ vsyncmintime += vsynctimebase / maxvpos_nom;
+ if (!vblank_found_chipset && (int)vsyncmaxtime - (int)vsyncmintime > 0) {
+ is_syncline = -1;
+ frame_time_t rpt = read_processor_time ();
+ /* No extra time left? Skip it */
+ if ((int)rpt - (int)vsyncmintime >= 0)
+ is_syncline = 0;
+ }
+ }
+ }
+
+#if 0
#ifdef JIT
if (currprefs.cachesize) {
if (currprefs.m68k_speed < 0) {
jitcount++;
- if (trigger_frh (jitcount)) {
+ if (isvsync () >= 0 && trigger_frh (jitcount)) {
frh_handler ();
}
- is_lastline = trigger_frh (jitcount + 1) && ! rpt_did_reset;
+ is_syncline = (trigger_frh (jitcount + 1) && ! rpt_did_reset) ? -1 : 0;
+ //write_log (L"%d %d\n", jitcount & (N_LINES - 1), is_syncline);
} else {
- is_lastline = 0;
+ is_syncline = 0;
}
+ if (vpos + 1 == maxvpos + lof_store)
+ is_syncline = 1;
} else {
#endif
- is_lastline = vpos + 1 == maxvpos + lof_store && currprefs.m68k_speed < 0;
+ is_syncline = (vpos + 1 == maxvpos + lof_store && currprefs.m68k_speed < 0) ? 1 : 0;
#ifdef JIT
}
+#endif
#endif
if (!nocustom ()) {
if (diw_change > 0)
diw_change--;
- if (is_lastline && isvsync_chipset () == -2 && !vsync_rendered && currprefs.gfx_apmode[0].gfx_vflip == 0) {
+ if (is_syncline > 0 && isvsync_chipset () == -2 && !vsync_rendered && currprefs.gfx_apmode[0].gfx_vflip == 0) {
/* fastest possible + last line and no vflip wait: render the frame as early as possible */
vsync_rendered = true;
vsync_handle_redraw (lof_store, lof_changed);
}
frame_shown = true;
}
+
rtg_vsynccheck ();
#if 0
static void hsync_handler (void)
{
- bool vs = is_vsync ();
+ bool vs = is_custom_vsync ();
hsync_handler_pre (vs);
if (vs) {
vsync_handler_pre ();
if (beamcon0 & 0x80)
return currprefs.ntscmode == 0;
return maxvpos_nom >= MAXVPOS_NTSC + (MAXVPOS_PAL - MAXVPOS_NTSC) / 2;
-}
\ No newline at end of file
+}
uae_u32 dos, crc, crc2;
int wasdelayed = drv->dskchange_time;
int sectable[MAX_SECTORS];
+ int oldcyl, oldside;
ret = 0;
+ *crc32 = 0;
+ oldcyl = drv->cyl;
+ oldside = side;
drv->cyl = 0;
side = 0;
- *crc32 = 0;
- if (!drive_insert (drv, p, num, p->floppyslots[num].df, true))
- return 1;
- if (!drv->diskfile)
+ if (!drive_insert (drv, p, num, p->floppyslots[num].df, true) || !drv->diskfile) {
+ drv->cyl = oldcyl;
+ side = oldside;
return 1;
+ }
*crc32 = zfile_crc32 (drv->diskfile);
decode_buffer (drv->bigmfmbuf, drv->cyl, 11, drv->ddhd, drv->filetype, &drvsec, sectable, 1);
+ drv->cyl = oldcyl;
+ side = oldside;
if (sectable[0] == 0 || sectable[1] == 0) {
ret = 2;
goto end;
--- /dev/null
+/*
+* UAE - The Un*x Amiga Emulator
+*
+* Event stuff
+*
+* Copyright 1995-2002 Bernd Schmidt
+* Copyright 1995 Alessandro Bissacco
+* Copyright 2000-2012 Toni Wilen
+*/
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "options.h"
+#include "events.h"
+
+unsigned long int event_cycles, nextevent, currcycle;
+int is_syncline;
+long cycles_to_next_event;
+long max_cycles_to_next_event;
+long cycles_to_hsync_event;
+unsigned long start_cycles;
+
+frame_time_t vsynctimebase, vsyncmintime, vsyncmaxtime;
+
+void events_schedule (void)
+{
+ int i;
+
+ unsigned long int mintime = ~0L;
+ for (i = 0; i < ev_max; i++) {
+ if (eventtab[i].active) {
+ unsigned long int eventtime = eventtab[i].evtime - currcycle;
+ if (eventtime < mintime)
+ mintime = eventtime;
+ }
+ }
+ nextevent = currcycle + mintime;
+}
+
+void do_cycles_slow (unsigned long cycles_to_add)
+{
+ if ((pissoff -= cycles_to_add) >= 0)
+ return;
+
+ cycles_to_add = -pissoff;
+ pissoff = 0;
+
+ while ((nextevent - currcycle) <= cycles_to_add) {
+ int i;
+
+ /* Keep only CPU emulation running while waiting for sync point. */
+ if (is_syncline) {
+ int rpt = read_processor_time ();
+ int v = rpt - vsyncmintime;
+ if (v > (int)vsynctimebase || v < -((int)vsynctimebase)) {
+ v = 0;
+ }
+ if (v < 0 && !vblank_found_chipset) {
+ pissoff = pissoff_value;
+ return;
+ }
+ is_syncline = 0;
+ }
+
+ cycles_to_add -= nextevent - currcycle;
+ currcycle = nextevent;
+
+ for (i = 0; i < ev_max; i++) {
+ if (eventtab[i].active && eventtab[i].evtime == currcycle) {
+ (*eventtab[i].handler)();
+ }
+ }
+ events_schedule ();
+
+
+ }
+ currcycle += cycles_to_add;
+}
+
+void MISC_handler (void)
+{
+ static bool dorecheck;
+ bool recheck;
+ int i;
+ evt mintime;
+ evt ct = get_cycles ();
+ static int recursive;
+
+ if (recursive) {
+ dorecheck = true;
+ return;
+ }
+ recursive++;
+ eventtab[ev_misc].active = 0;
+ recheck = true;
+ while (recheck) {
+ recheck = false;
+ mintime = ~0L;
+ for (i = 0; i < ev2_max; i++) {
+ if (eventtab2[i].active) {
+ if (eventtab2[i].evtime == ct) {
+ eventtab2[i].active = false;
+ eventtab2[i].handler (eventtab2[i].data);
+ if (dorecheck || eventtab2[i].active) {
+ recheck = true;
+ dorecheck = false;
+ }
+ } else {
+ evt eventtime = eventtab2[i].evtime - ct;
+ if (eventtime < mintime)
+ mintime = eventtime;
+ }
+ }
+ }
+ }
+ if (mintime != ~0L) {
+ eventtab[ev_misc].active = true;
+ eventtab[ev_misc].oldcycles = ct;
+ eventtab[ev_misc].evtime = ct + mintime;
+ events_schedule ();
+ }
+ recursive--;
+}
+
+
+void event2_newevent_xx (int no, evt t, uae_u32 data, evfunc2 func)
+{
+ evt et;
+ static int next = ev2_misc;
+
+ et = t + get_cycles ();
+ if (no < 0) {
+ no = next;
+ for (;;) {
+ if (!eventtab2[no].active)
+ break;
+ if (eventtab2[no].evtime == et && eventtab2[no].handler == func && eventtab2[no].data == data)
+ break;
+ no++;
+ if (no == ev2_max)
+ no = ev2_misc;
+ if (no == next) {
+ write_log (L"out of event2's!\n");
+ return;
+ }
+ }
+ next = no;
+ }
+ eventtab2[no].active = true;
+ eventtab2[no].evtime = et;
+ eventtab2[no].handler = func;
+ eventtab2[no].data = data;
+ MISC_handler ();
+}
+
#include "machdep/rpt.h"
-extern volatile frame_time_t vsynctime, vsyncmintime;
+extern frame_time_t vsynctimebase, vsyncmintime, vsyncmaxtime;
extern void reset_frame_rate_hack (void);
-extern int rpt_available;
extern frame_time_t syncbase;
extern unsigned long int vsync_cycles;
extern unsigned long start_cycles;
extern void compute_vsynctime (void);
extern void init_eventtab (void);
extern void do_cycles_ce (unsigned long cycles);
+extern void events_schedule (void);
+extern void do_cycles_slow (unsigned long cycles_to_add);
+extern void do_cycles_fast (unsigned long cycles_to_add);
+
extern int is_cycle_ce (void);
-extern unsigned long currcycle, nextevent, is_lastline;
+extern unsigned long currcycle, nextevent;
+extern int is_syncline;
typedef void (*evfunc)(void);
typedef void (*evfunc2)(uae_u32);
ev2_max = 12
};
+extern int pissoff_value;
+extern signed long pissoff;
+
+#define countdown pissoff
+#define do_cycles do_cycles_slow
+
extern struct ev eventtab[ev_max];
extern struct ev2 eventtab2[ev2_max];
-#if 0
+extern volatile bool vblank_found_chipset;
+extern volatile bool vblank_found_rtg;
+
+STATIC_INLINE void cycles_do_special (void)
+{
#ifdef JIT
-#include "events_jit.h"
-#else
-#include "events_normal.h"
+ if (currprefs.cachesize) {
+ if (pissoff >= 0)
+ pissoff = -1;
+ } else
#endif
-#else
-#include "events_jit.h"
+ {
+ pissoff = 0;
+ }
+}
+
+STATIC_INLINE void do_extra_cycles (unsigned long cycles_to_add)
+{
+ pissoff -= cycles_to_add;
+}
+
+STATIC_INLINE unsigned long int get_cycles (void)
+{
+ return currcycle;
+}
+
+STATIC_INLINE void set_cycles (unsigned long int x)
+{
+ currcycle = x;
+ eventtab[ev_hsync].oldcycles = x;
+#ifdef EVT_DEBUG
+ if (currcycle & (CYCLE_UNIT - 1))
+ write_log (L"%x\n", currcycle);
#endif
+}
STATIC_INLINE int current_hpos (void)
{
}
extern void MISC_handler (void);
-
-STATIC_INLINE void event2_newevent_xx (int no, evt t, uae_u32 data, evfunc2 func)
-{
- evt et;
- static int next = ev2_misc;
-
- et = t + get_cycles ();
- if (no < 0) {
- no = next;
- for (;;) {
- if (!eventtab2[no].active)
- break;
- if (eventtab2[no].evtime == et && eventtab2[no].handler == func && eventtab2[no].data == data)
- break;
- no++;
- if (no == ev2_max)
- no = ev2_misc;
- if (no == next) {
- write_log (L"out of event2's!\n");
- return;
- }
- }
- next = no;
- }
- eventtab2[no].active = true;
- eventtab2[no].evtime = et;
- eventtab2[no].handler = func;
- eventtab2[no].data = data;
- MISC_handler ();
-}
+extern void event2_newevent_xx (int no, evt t, uae_u32 data, evfunc2 func);
STATIC_INLINE void event2_newevent_x (int no, evt t, uae_u32 data, evfunc2 func)
{
func (data);
return;
}
-
event2_newevent_xx (no, t * CYCLE_UNIT, data, func);
}
event2_newevent_x (-1, t, data, func);
}
-
STATIC_INLINE void event2_remevent (int no)
{
eventtab2[no].active = 0;
int gfx_vsyncmode;
int gfx_backbuffers;
bool gfx_interlaced;
+ int gfx_refreshrate;
};
struct uae_prefs {
bool gfx_autoresolution;
int gfx_autoresolution_minv, gfx_autoresolution_minh;
bool gfx_scandoubler;
- int gfx_refreshrate;
struct apmode gfx_apmode[2];
int gfx_resolution;
int gfx_vresolution;
float sw2 = dw * tin_w / window_w;
float sh2 = dh * tin_h / window_h;
- maskmult.x = 1; //sw2 * maskmult_x / w;
- maskmult.y = 1; //sh2 * maskmult_y / h;
+ maskmult.x = sw2 * maskmult_x / w;
+ maskmult.y = sh2 * maskmult_y / h;
maskshift.x = 1.0f / maskmult_x;
maskshift.y = 1.0f / maskmult_y;
ddraw_fs_hack_free ();
}
+#define VBLANKDEBUG 0
+
bool D3D_getvblankpos (int *vpos)
{
HRESULT hr;
D3DRASTER_STATUS rt;
-
+#if VBLANKDEBUG
+ static UINT lastline;
+ static BOOL lastinvblank;
+#endif
*vpos = -2;
if (!isd3d ())
return false;
if (rt.ScanLine > maxscanline)
maxscanline = rt.ScanLine;
*vpos = rt.ScanLine;
+#if VBLANKDEBUG
+ if (lastline != rt.ScanLine || lastinvblank != rt.InVBlank) {
+ write_log(L"%d:%d ", rt.InVBlank ? 1 : 0, rt.ScanLine);
+ lastline = rt.ScanLine;
+ lastinvblank = rt.InVBlank;
+ }
+#endif
if (rt.InVBlank != 0)
*vpos = -1;
return true;
vsync2 = 0;
int hzmult = 0;
if (isfullscreen () > 0) {
- dpp.FullScreen_RefreshRateInHz = currprefs.gfx_refreshrate > 0 ? currprefs.gfx_refreshrate : 0;
+ dpp.FullScreen_RefreshRateInHz = ap->gfx_refreshrate > 0 ? ap->gfx_refreshrate : 0;
modeex.RefreshRate = dpp.FullScreen_RefreshRateInHz;
if (vsync > 0) {
dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
#if defined(NATMEM_OFFSET)
+/* JIT can access few bytes outside of memory block of it executes code at the very end of memory block */
#define BARRIER 32
+
#define MAXZ3MEM 0x7F000000
#define MAXZ3MEM64 0xF0000000
if(!_tcscmp (shmids[shmid].name, L"chip")) {
shmaddr=natmem_offset;
got = TRUE;
- if ((currprefs.fastmem_size == 0 && (currprefs.rtgmem_size == 0 && !currprefs.rtgmem_type)) || currprefs.chipmem_size < 2 * 1024 * 1024)
+ if (getz2endaddr () <= 2 * 1024 * 1024 || currprefs.chipmem_size < 2 * 1024 * 1024)
size += BARRIER;
}
if(!_tcscmp (shmids[shmid].name, L"kick")) {
}
if(!_tcscmp (shmids[shmid].name, L"ramsey_low")) {
shmaddr=natmem_offset + a3000lmem_start;
+ if (!currprefs.mbresmem_high_size)
+ size += BARRIER;
got = TRUE;
}
if(!_tcscmp (shmids[shmid].name, L"ramsey_high")) {
shmaddr=natmem_offset + a3000hmem_start;
+ size += BARRIER;
got = TRUE;
}
if(!_tcscmp (shmids[shmid].name, L"z3")) {
put_byte (amigamemptr + PSSO_ModeInfo_second_union, 14);
put_long (amigamemptr + PSSO_ModeInfo_PixelClock,
- width * height * (currprefs.gfx_refreshrate ? abs (currprefs.gfx_refreshrate) : default_freq));
+ width * height * (currprefs.gfx_apmode[1].gfx_refreshrate ? abs (currprefs.gfx_apmode[1].gfx_refreshrate) : default_freq));
}
struct modeids {
}
-static void init_picasso_screen(void);
+static void init_picasso_screen (void);
void picasso_enablescreen (int on)
{
if (!init_picasso_screen_called)
- init_picasso_screen();
+ init_picasso_screen ();
picasso_refresh ();
checkrtglibrary();
#endif
}
-extern int vsynctime_orig;
+extern int vsynctimebase_orig;
#ifndef AVIOUTPUT
static int avioutput_audio;
if (avioutput_audio && avioutput_enabled && avioutput_nosoundsync)
mult = 1000.0;
if (isvsync_chipset () || (avioutput_audio && avioutput_enabled && !currprefs.cachesize)) {
- vsynctime = vsynctime_orig;
+ vsynctimebase = vsynctimebase_orig;
scaled_sample_evtime = scaled_sample_evtime_orig * mult / 1000.0;
} else if (currprefs.cachesize || currprefs.m68k_speed != 0) {
- vsynctime = (long)(((double)vsynctime_orig) * mult / 1000.0);
+ vsynctimebase = (long)(((double)vsynctimebase_orig) * mult / 1000.0);
scaled_sample_evtime = scaled_sample_evtime_orig;
} else {
- vsynctime = (long)(((double)vsynctime_orig) * mult / 1000.0);
+ vsynctimebase = (long)(((double)vsynctimebase_orig) * mult / 1000.0);
scaled_sample_evtime = scaled_sample_evtime_orig;
}
}
int log_net;
int log_vsync;
int uaelib_debug;
-int pissoff_value = 25000;
+int pissoff_value = 25000 * CYCLE_UNIT;
unsigned int fpucontrol;
int extraframewait = 0;
return 2;
}
if (!_tcscmp (arg, L"jitevent")) {
- pissoff_value = getval (np);
+ pissoff_value = getval (np) * CYCLE_UNIT;
return 2;
}
if (!_tcscmp (arg, L"inputrecorddebug")) {
write_log (L"%d: '%s'\n", i + 1, argv2[i]);
}
if (WIN32_RegisterClasses () && WIN32_InitLibraries ()) {
- DEVMODE devmode;
DWORD i;
WIN32_HandleRegistryStuff ();
write_log (L"%d:%s: %s\n", i, type == SOUND_DEVICE_XAUDIO2 ? L"XA" : (type == SOUND_DEVICE_DS ? L"DS" : (type == SOUND_DEVICE_AL ? L"AL" : (type == SOUND_DEVICE_WASAPI ? L"WA" : (type == SOUND_DEVICE_WASAPI_EXCLUSIVE ? L"WX" : L"PA")))), record_devices[i]->name);
}
write_log (L"done\n");
+#if 0
+ DEVMODE devmode;
memset (&devmode, 0, sizeof (devmode));
devmode.dmSize = sizeof (DEVMODE);
if (EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &devmode)) {
else
default_freq = 60;
}
+#endif
WIN32_InitLang ();
WIN32_InitHtmlHelp ();
DirectDraw_Release ();
#define LANG_DLL 1
//#define WINUAEBETA L""
-#define WINUAEBETA L"Beta 20"
-#define WINUAEDATE MAKEBD(2012, 3, 4)
+#define WINUAEBETA L"Beta 21"
+#define WINUAEDATE MAKEBD(2012, 3, 10)
#define WINUAEEXTRA L""
//#define WINUAEEXTRA L"AmiKit Preview"
#define WINUAEREV L""
static struct winuae_currentmode *currentmode = ¤tmodestruct;
static int wasfullwindow_a, wasfullwindow_p;
-static int vblankbasewait, vblankbasewait2, vblankbasewait3, vblankbasefull;
+static int vblankbasewait1, vblankbasewait2, vblankbasewait3, vblankbasefull;
static bool vblankbaselace;
static int vblankbaselace_chipset;
static bool vblankthread_oddeven;
} else {
dowait = false;
}
- if (dowait)
+ if (dowait && currprefs.m68k_speed >= 0)
sleep_millis_main (1);
}
-static void changevblankthreadmode (int newmode)
+static void changevblankthreadmode_do (int newmode, bool fast)
{
int t = vblankthread_counter;
vblank_found = false;
flipevent = NULL;
flipevent2 = NULL;
}
- while (t == vblankthread_counter && vblankthread_mode > 0);
+ if (!fast) {
+ while (t == vblankthread_counter && vblankthread_mode > 0);
+ }
+}
+
+static void changevblankthreadmode (int newmode)
+{
+ changevblankthreadmode_do (newmode, false);
+}
+static void changevblankthreadmode_fast (int newmode)
+{
+ changevblankthreadmode_do (newmode, true);
}
int WIN32GFX_IsPicassoScreen (void)
static int init_round;
static BOOL doInit (void);
-int default_freq = 0;
+int default_freq = 60;
HWND hStatusWnd = NULL;
static uae_u8 scrlinebuf[4096 * 4]; /* this is too large, but let's rather play on the safe side here */
-
struct MultiDisplay *getdisplay (struct uae_prefs *p)
{
int i;
if (screen_is_picasso) {
currentmode->current_width = picasso96_state.Width;
currentmode->current_height = picasso96_state.Height;
- currentmode->frequency = abs (currprefs.gfx_refreshrate > default_freq ? currprefs.gfx_refreshrate : default_freq);
+ if (currprefs.win32_rtgvblankrate == 0)
+ currentmode->frequency = abs (currprefs.gfx_apmode[0].gfx_refreshrate);
+ else if (currprefs.win32_rtgvblankrate < 0)
+ currentmode->frequency = 0;
+ else
+ currentmode->frequency = abs (currprefs.gfx_apmode[1].gfx_refreshrate >= 50 ? currprefs.gfx_apmode[1].gfx_refreshrate : 50);
if (currprefs.gfx_apmode[1].gfx_vsync)
currentmode->vsync = 1 + currprefs.gfx_apmode[1].gfx_vsyncmode;
} else {
#endif
currentmode->current_width = currprefs.gfx_size.width;
currentmode->current_height = currprefs.gfx_size.height;
- currentmode->frequency = abs (currprefs.gfx_refreshrate);
+ currentmode->frequency = abs (currprefs.gfx_apmode[0].gfx_refreshrate);
if (currprefs.gfx_apmode[0].gfx_vsync)
currentmode->vsync = 1 + currprefs.gfx_apmode[0].gfx_vsyncmode;
#ifdef PICASSO96
c |= currprefs.gfx_apmode[1].gfx_vsync != changed_prefs.gfx_apmode[1].gfx_vsync ? 2 | 16 : 0;
c |= currprefs.gfx_apmode[0].gfx_vsyncmode != changed_prefs.gfx_apmode[0].gfx_vsyncmode ? 2 | 16 : 0;
c |= currprefs.gfx_apmode[1].gfx_vsyncmode != changed_prefs.gfx_apmode[1].gfx_vsyncmode ? 2 | 16 : 0;
- c |= currprefs.gfx_refreshrate != changed_prefs.gfx_refreshrate ? 2 | 16 : 0;
+ c |= currprefs.gfx_apmode[0].gfx_refreshrate != changed_prefs.gfx_apmode[0].gfx_refreshrate ? 2 | 16 : 0;
+ c |= currprefs.gfx_apmode[1].gfx_refreshrate != changed_prefs.gfx_apmode[1].gfx_refreshrate ? 2 | 16 : 0;
c |= currprefs.gfx_autoresolution != changed_prefs.gfx_autoresolution ? (2|8|16) : 0;
c |= currprefs.gfx_api != changed_prefs.gfx_api ? (1|8|32) : 0;
currprefs.gfx_apmode[1].gfx_vsync = changed_prefs.gfx_apmode[1].gfx_vsync;
currprefs.gfx_apmode[0].gfx_vsyncmode = changed_prefs.gfx_apmode[0].gfx_vsyncmode;
currprefs.gfx_apmode[1].gfx_vsyncmode = changed_prefs.gfx_apmode[1].gfx_vsyncmode;
- currprefs.gfx_refreshrate = changed_prefs.gfx_refreshrate;
+ currprefs.gfx_apmode[0].gfx_refreshrate = changed_prefs.gfx_apmode[0].gfx_refreshrate;
+ currprefs.gfx_apmode[1].gfx_refreshrate = changed_prefs.gfx_apmode[1].gfx_refreshrate;
config_changed = 1;
if (!quick)
} else {
newh = found->res.height;
changed_prefs.gfx_size_fs.height = newh;
- changed_prefs.gfx_refreshrate = hz;
+ changed_prefs.gfx_apmode[0].gfx_refreshrate = hz;
if (changed_prefs.gfx_size_fs.height != currprefs.gfx_size_fs.height ||
- changed_prefs.gfx_refreshrate != currprefs.gfx_refreshrate) {
+ changed_prefs.gfx_apmode[0].gfx_refreshrate != currprefs.gfx_apmode[0].gfx_refreshrate) {
write_log (L"refresh rate changed to %d, new screenmode %dx%d\n", hz, w, newh);
config_changed = 1;
}
static bool getvblankpos (int *vp)
{
int sl;
+#if 0
+ frame_time_t t = read_processor_time ();
+#endif
*vp = -2;
if (currprefs.gfx_api) {
if (!D3D_getvblankpos (&sl))
if (!DD_getvblankpos (&sl))
return false;
}
+#if 0
+ t = read_processor_time () - t;
+ write_log (L"(%d:%d)", t, sl);
+#endif
prevvblankpos = sl;
if (sl > maxscanline)
maxscanline = sl;
return 0;
}
+static int frame_missed, frame_counted, frame_errors;
+static int frame_usage, frame_usage_avg, frame_usage_total;
+extern int log_vsync;
+static bool dooddevenskip;
+
static bool vblanklaceskip (void)
{
if (vblankbaselace_chipset >= 0 && vblankbaselace) {
// idle mode
Sleep (100);
} else if (vblankthread_mode == VBLANKTH_ACTIVE_WAIT) {
- sleep_millis (ap->gfx_vflip ? 2 : 1);
+ sleep_millis (ap->gfx_vflip && currprefs.m68k_speed >= 0 ? 2 : 1);
} else if (vblankthread_mode == VBLANKTH_ACTIVE_START) {
// do not start until vblank has been passed
bool vb = false;
// busy wait mode
frame_time_t t = read_processor_time ();
bool donotwait = false;
- int vs = isvsync_chipset ();
if (!vblank_found) {
+ int vs = isvsync_chipset ();
// immediate vblank if mismatched frame type
if (vs < 0 && vblanklaceskip ()) {
vblank_found = true;
if (firstvblankbasewait2 == false) {
firstvblankbasewait2 = true;
vblank_getstate (&vb);
+ if (!dooddevenskip && ap->gfx_vflip > 0) {
+ doflipevent ();
+ }
}
ok = vblank_getstate (&vb);
if (!ok || vb) {
donotwait = true;
}
}
- if (t - vblank_prev_time > vblankbasefull * 3)
+ if (t - vblank_prev_time > vblankbasefull * 3) {
+ vblank_found = true;
+ vblank_found_rtg = true;
+ vblank_found_chipset = true;
vblankthread_mode = VBLANKTH_IDLE;
+ }
if (!donotwait || ap->gfx_vflip || picasso_on)
- sleep_millis (ap->gfx_vflip ? 2 : 1);
+ sleep_millis (ap->gfx_vflip && currprefs.m68k_speed >= 0 ? 2 : 1);
} else {
break;
}
return 0;
}
-static int frame_missed, frame_counted, frame_errors;
-static int frame_usage, frame_usage_avg, frame_usage_total;
-extern int log_vsync;
-static bool dooddevenskip;
-
bool vsync_busywait_check (void)
{
return vblankthread_mode == VBLANKTH_ACTIVE || vblankthread_mode == VBLANKTH_ACTIVE_WAIT;
if (!dooddevenskip) {
vsync_notvblank ();
while (!vblank_found && vblankthread_mode == VBLANKTH_ACTIVE) {
- vsync_sleep (false);
+ vsync_sleep (currprefs.m68k_speed < 0);
}
}
- changevblankthreadmode (VBLANKTH_ACTIVE_WAIT);
+ changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT);
return thread_vblank_time;
}
void vsync_busywait_start (void)
{
+#if 0
struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
if (!dooddevenskip) {
vsync_notvblank ();
doflipevent ();
}
}
- changevblankthreadmode (VBLANKTH_ACTIVE_START);
+#endif
+ changevblankthreadmode_fast (VBLANKTH_ACTIVE_START);
vblank_prev_time = thread_vblank_time;
}
}
if (!doskip) {
- while (!framelost && read_processor_time () - prevtime < vblankbasewait) {
+ while (!framelost && read_processor_time () - prevtime < vblankbasewait1) {
vsync_sleep (false);
}
v = vblank_wait ();
depth = (currentmode->native_depth + 7) / 8;
}
- rate = currprefs.gfx_refreshrate;
+ rate = ap->gfx_refreshrate;
mode = isfullscreen ();
rv = vsyncmemory;
while (rv) {
tsum2 = tsum / div;
vblankbasefull = (syncbase / tsum2);
- vblankbasewait = (syncbase / tsum2) * 3 / 4;
+ vblankbasewait1 = (syncbase / tsum2) * 75 / 100;
vblankbasewait2 = (syncbase / tsum2) * 70 / 100;
vblankbasewait3 = (syncbase / tsum2) * 90 / 100;
vblankbaselace = lace;
changed_prefs.gfx_filter = currprefs.gfx_filter = 0;
currentmode->current_depth = currentmode->native_depth;
gfxmode_reset ();
+ DirectDraw_Start ();
ret = -1;
goto oops;
}
_tcscat (hz, L" NTSC");
if (type)
_tcscat (hz, L" (*)");
- if (abs (workprefs.gfx_refreshrate) == freq)
+ if (abs (workprefs.gfx_apmode[0].gfx_refreshrate) == freq)
_tcscpy (hz2, hz);
SendDlgItemMessage (hDlg, IDC_REFRESHRATE, CB_ADDSTRING, 0, (LPARAM)hz);
}
if (index == CB_ERR) {
WIN32GUI_LoadUIString (IDS_VSYNC_DEFAULT, txt, sizeof (txt) / sizeof (TCHAR));
SendDlgItemMessage(hDlg, IDC_REFRESHRATE, CB_SELECTSTRING, i, (LPARAM)txt);
- workprefs.gfx_refreshrate = 0;
+ workprefs.gfx_apmode[0].gfx_refreshrate = 0;
}
}
if (posn1 == CB_ERR)
return;
if (posn1 == 0) {
- workprefs.gfx_refreshrate = 0;
+ workprefs.gfx_apmode[0].gfx_refreshrate = 0;
} else {
posn1--;
- workprefs.gfx_refreshrate = md->DisplayModes[dmode].refresh[posn1];
+ workprefs.gfx_apmode[0].gfx_refreshrate = md->DisplayModes[dmode].refresh[posn1];
}
values_to_displaydlg (hDlg);
} else if (LOWORD (wParam) == IDC_DA_MODE) {
<ClCompile Include="..\..\archivers\zip\unzip.cpp" />
<ClCompile Include="..\..\aros.rom.cpp" />
<ClCompile Include="..\..\cpuemu_21.cpp" />
+ <ClCompile Include="..\..\events.cpp" />
<ClCompile Include="..\..\hrtmon.rom.cpp" />
<ClCompile Include="..\..\inputrecord.cpp" />
<ClCompile Include="..\..\specialmonitors.cpp" />
<ClCompile Include="..\..\specialmonitors.cpp">
<Filter>common</Filter>
</ClCompile>
+ <ClCompile Include="..\..\events.cpp">
+ <Filter>common</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\resources\35floppy.ico">
+Beta 21: (Fastest possible vsync should be fixed finally, only some testing left to do)
+
+- Direct3D masks and scanlines fixed, forgotten testing code.. (b20)
+- 2.3.2 "stop the cpu and wait until blitter has finished if any blitter register is accessed while blitter is busy and
+ cpu mode is fastest possible" was broken and could cause side-effects in some situations.
+- Direct3D to DirectDraw fallback if DirectX is not recent enough crashed. (b5)
+- Keyboard lost sync state emulated, needed with some programs that don't handshake all buffered key codes but still clear
+ the CIA keyboard interrupt flag, this caused dead keyboard after b1 update. Now keyboard should be fully emulated.
+- Quickstart panel disk insert always reset track position to zero. (forgot to restore old track after checking disk
+ type and bootable state, bug since Quickstart was introduced!) Fixes Wrath of Demon disk swaps.
+- Z2 RTG changes broke chip RAM "memory barrier" causing crash if JIT executed code at the very end of chip RAM. (b16)
+
+I finally really examined and even understood (I think..) how fastest possible and JIT modes handle CPU emulation,
+(in reality fastest possible without JIT didn't really handle it all, other UAE ports most likely have exact same issue):
+Some unnecessary and big event code inlining also removed (shorter code, should be faster on modern CPUs due to less cache trashing)
+
+- Huge improvement in fastest possible CPU (with or without JIT) + low latency vsync performance.
+- Fastest possible without JIT performance improved in non-vsync modes. It now executes small chunks of extra code after
+ each scanline instead (as long as there is time, the faster the host CPU, the more extra time there is) of single huge
+ chunk just before vsync. JIT basically does the same but because it has "unknown" timing, it may execute "too much"
+ code first and then skip multiple scanlines until there is enough time again.
+- Immediate blitter is now 100% immediate. Fastest possible (with or without JIT) performance greatly improved (10x+ possible!)
+ if program does lots of small blits. Previously, even in immediate blitter mode, blitter wait caused CPU emulator to waste
+ its extra "fastest possible time slot" by doing absolutely nothing else than waiting the blitter that never happened. It can't
+ happen until next scanline, during extra fastest CPU "slots" chipset emulation has to be paused.
+
+Fastest possible CPU throttling option will be also possible, this will be done later..
+
+NOTE: Above changes WILL break some games/demos that (accidentally) worked previously. It is 100% guaranteed!
+
Beta 20:
- Fixed DirectDraw on screen led status bar surface allocation error when switching modes in some situations.