#include "blitter.h"
#include "ini.h"
#include "readcpu.h"
+#include "cputbl.h"
#define TRACE_SKIP_INS 1
#define TRACE_MATCH_PC 2
int debugger_active;
static int debug_rewind;
static int memwatch_triggered;
+static int inside_debugger;
int memwatch_access_validator;
int memwatch_enabled;
int debugging;
void deactivate_debugger (void)
{
+ inside_debugger = 0;
debugger_active = 0;
debugging = 0;
exception_debugging = 0;
debugger_load_libraries();
+ inside_debugger = 1;
debug_pc = 0xffffffff;
trace_mode = 0;
if (debugger_active) {
{
uae_u32 val = *valp;
- if (debugging > 0)
+ if (inside_debugger)
return 1;
if (mungwall)
struct sprite_entry
{
- unsigned short pos;
- unsigned short max;
- unsigned int first_pixel;
+ uae_u16 pos;
+ uae_u16 max;
+ uae_u32 first_pixel;
bool has_attached;
};
#include "traps.h"
#define UAEMAJOR 4
-#define UAEMINOR 2
-#define UAESUBREV 1
+#define UAEMINOR 3
+#define UAESUBREV 0
#define MAX_AMIGADISPLAYS 4
ap->gfx_strobo = prefs->lightboost_strobo;
}
} else {
- if (ap->gfx_backbuffers > 0 && prefs->gfx_api > 1)
+ if (ap->gfx_backbuffers > 0 && (prefs->gfx_api > 1 || prefs->gfx_variable_sync))
ap->gfx_strobo = prefs->lightboost_strobo;
// no vsync: wait if triple bufferirng
if (ap->gfx_backbuffers >= 2)
color[1] = 0;
color[2] = 0;
color[3] = 0;
+ // Bind the render target view and depth stencil buffer to the output render pipeline.
+ d3d->m_deviceContext->OMSetRenderTargets(1, &d3d->m_renderTargetView, NULL);
// Clear the back buffer.
d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color);
+ d3d->m_deviceContext->Flush();
}
static void do_present(struct d3d11struct *d3d)
UINT syncinterval = d3d->vblankintervals;
// only if no vsync or low latency vsync
if (d3d->m_tearingSupport && (d3d->swapChainDesc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) && (!vsync || apm->gfx_vsyncmode)) {
- if (apm->gfx_vsyncmode || d3d - d3d11data > 0 || currprefs.turbo_emulation) {
+ if (apm->gfx_vsyncmode || d3d - d3d11data > 0 || currprefs.turbo_emulation || currprefs.gfx_variable_sync) {
presentFlags |= DXGI_PRESENT_ALLOW_TEARING;
syncinterval = 0;
}
<IntDir Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">false</LinkIncremental>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">
+ <PreLinkEventUseInBuild>false</PreLinkEventUseInBuild>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PreLinkEventUseInBuild>false</PreLinkEventUseInBuild>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseXP|Win32'">
+ <PreLinkEventUseInBuild>false</PreLinkEventUseInBuild>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">
+ <PreLinkEventUseInBuild>false</PreLinkEventUseInBuild>
+ </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>.\Release/gencpu_msvc.tlb</TypeLibraryName>
<Culture>0x0409</Culture>
</ResourceCompile>
<PreLinkEvent>
- <Message>deleting gencpu files</Message>
- <Command>del ..\..\cputbl.h
-del ..\..\cpustbl.cpp
-del ..\..\cpuemu.cpp
-
-</Command>
+ <Message>
+ </Message>
+ <Command>
+ </Command>
</PreLinkEvent>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
</Link>
<PostBuildEvent>
<Message>generating gencpu files</Message>
- <Command>cd ..\..
-od-win32\gencpu_msvc\gencpu.exe
-del od-win32\gencpu_msvc\gencpu.exe
-</Command>
+ <Command>cd ..\..\
+.\od-win32\gencpu_msvc\gencpu.exe</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseXP|Win32'">
<Culture>0x0409</Culture>
</ResourceCompile>
<PreLinkEvent>
- <Message>deleting gencpu files</Message>
- <Command>del ..\..\cputbl.h
-del ..\..\cpustbl.cpp
-del ..\..\cpuemu.cpp
-
-</Command>
+ <Message>
+ </Message>
+ <Command>
+ </Command>
</PreLinkEvent>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
</Link>
<PostBuildEvent>
<Message>generating gencpu files</Message>
- <Command>cd ..\..
-od-win32\gencpu_msvc\gencpu.exe
-del od-win32\gencpu_msvc\gencpu.exe
-</Command>
+ <Command>cd ..\..\
+.\od-win32\gencpu_msvc\gencpu.exe</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">
<Culture>0x0409</Culture>
</ResourceCompile>
<PreLinkEvent>
- <Message>deleting gencpu files</Message>
- <Command>del ..\..\cputbl.h
-del ..\..\cpustbl.cpp
-
-
-</Command>
+ <Message>
+ </Message>
+ <Command>
+ </Command>
</PreLinkEvent>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
</Link>
<PostBuildEvent>
<Message>generating gencpu files</Message>
- <Command>cd ..\..
-od-win32\gencpu_msvc\gencpu.exe
-
-</Command>
+ <Command>cd ..\..\
+.\od-win32\gencpu_msvc\gencpu.exe</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">
<Culture>0x0409</Culture>
</ResourceCompile>
<PreLinkEvent>
- <Message>deleting gencpu files</Message>
+ <Message>
+ </Message>
<Command>
</Command>
</PreLinkEvent>
</Link>
<PostBuildEvent>
<Message>generating gencpu files</Message>
- <Command>cd ..\..
-od-win32\gencpu_msvc\gencpu.exe
-</Command>
+ <Command>cd ..\..\
+.\od-win32\gencpu_msvc\gencpu.exe</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 4,2,2,0
- PRODUCTVERSION 4,2,2,0
+ FILEVERSION 4,3,0,0
+ PRODUCTVERSION 4,3,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "WinUAE"
- VALUE "FileVersion", "4.2.2.0"
+ VALUE "FileVersion", "4.3.0.0"
VALUE "InternalName", "WinUAE"
VALUE "LegalCopyright", "© 1996-2019 under the GNU Public License (GPL)"
VALUE "OriginalFilename", "WinUAE.exe"
VALUE "ProductName", "WinUAE"
- VALUE "ProductVersion", "4.2.2.0"
+ VALUE "ProductVersion", "4.3.0.0"
END
END
BLOCK "VarFileInfo"
#endif
if (!mon_cursorclipped)
return;
- ClipCursor(NULL);
- ReleaseCapture();
- ShowCursor(TRUE);
+ if (!ClipCursor(NULL))
+ write_log(_T("ClipCursor %08x\n"), GetLastError());
+ if (!ReleaseCapture())
+ write_log(_T("ReleaseCapture %08x\n"), GetLastError());
+ int c = ShowCursor(TRUE);
+ write_log(_T("ShowCursor %d\n"), c);
mon_cursorclipped = 0;
}
return _tstol (tmp);
}
-static int checkversion (TCHAR *vs)
+static int checkversion (TCHAR *vs, int *verp)
{
int ver;
if (_tcslen (vs) < 10)
ver = parseversion (&vs) << 16;
ver |= parseversion (&vs) << 8;
ver |= parseversion (&vs);
+ if (verp)
+ *verp = ver;
if (ver >= ((UAEMAJOR << 16) | (UAEMINOR << 8) | UAESUBREV))
return 0;
return 1;
}
size = sizeof (version) / sizeof (TCHAR);
if (regquerystr (NULL, _T("Version"), version, &size)) {
- if (checkversion (version))
+ int ver = 0;
+ if (checkversion (version, &ver))
regsetstr (NULL, _T("Version"), VersionStr);
+ // Reset GUI setting if pre-4.3.0
+ if (ver > 0x030000 && ver < 0x040300) {
+ regdelete(NULL, _T("GUISizeX"));
+ regdelete(NULL, _T("GUISizeY"));
+ regdelete(NULL, _T("GUISizeFWX"));
+ regdelete(NULL, _T("GUISizeFWY"));
+ regdelete(NULL, _T("GUISizeFSX"));
+ regdelete(NULL, _T("GUISizeFSY"));
+ }
} else {
regsetstr (NULL, _T("Version"), VersionStr);
}
size = sizeof (version) / sizeof (TCHAR);
if (regquerystr (NULL, _T("ROMCheckVersion"), version, &size)) {
- if (checkversion (version)) {
+ if (checkversion (version, NULL)) {
if (regsetstr (NULL, _T("ROMCheckVersion"), VersionStr))
forceroms = 1;
}
void systray (HWND hwnd, int remove)
{
- static const GUID iconguid = { 0xdac2e99b, 0xe8f6, 0x4150, { 0x98, 0x46, 0xd, 0x4a, 0x61, 0xfb, 0xdd, 0x03 } };
+ static const GUID iconguid = { 0x6974bfc1, 0x898b, 0x4157, { 0xa4, 0x30, 0x43, 0x6b, 0xa0, 0xdd, 0x5d, 0xf2 } };
NOTIFYICONDATA nid;
BOOL v;
static bool noguid;
if (!remove) {
// if guid identifier: always remove first.
// old icon may not have been removed due to crash etc
- Shell_NotifyIcon(NIM_DELETE, &nid);
+ v = Shell_NotifyIcon(NIM_DELETE, &nid);
}
}
v = Shell_NotifyIcon (remove ? NIM_DELETE : NIM_ADD, &nid);
#define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
#define GETBDD(x) ((x) % 100)
-#define WINUAEPUBLICBETA 0
+#define WINUAEPUBLICBETA 1
#define LANG_DLL 1
#define LANG_DLL_FULL_VERSION_MATCH 0
#if WINUAEPUBLICBETA
-#define WINUAEBETA _T("")
+#define WINUAEBETA _T("1")
#else
#define WINUAEBETA _T("")
#endif
-#define WINUAEDATE MAKEBD(2019, 5, 16)
+#define WINUAEDATE MAKEBD(2019, 10, 19)
//#define WINUAEEXTRA _T("AmiKit Preview")
//#define WINUAEEXTRA _T("Amiga Forever Edition")
}
}
static frame_time_t strobo_time;
-static volatile bool strobo_active;
+static volatile int strobo_active;
static volatile bool strobo_active2;
static void CALLBACK blackinsertion_cb(
{
struct AmigaMonitor *mon = &AMonitors[0];
if (mon->screen_is_initialized) {
+ if (strobo_active) {
+ }
+
while (strobo_active) {
frame_time_t ct = read_processor_time();
int diff = (int)strobo_time - (int)ct;
break;
}
if (diff <= 0) {
- if (strobo_active2)
- show_screen_special();
+ if (strobo_active) {
+ gfx_lock();
+ D3D_showframe_special(0, 1);
+ gfx_unlock();
+ }
break;
}
if (diff > vsynctimebase / 4) {
}
}
}
- strobo_active = false;
+ strobo_active = 0;
}
float target_adjust_vblank_hz(int monid, float hz)
return;
}
if (mon->currentmode.flags & DM_D3D) {
+ if (ap->gfx_strobo && currprefs.gfx_variable_sync) {
+ float vblank = vblank_hz;
+ int ratio = currprefs.lightboost_strobo_ratio;
+ int ms = (int)(1000 / vblank);
+ int waitms = ms * ratio / 100 - 1;
+ strobo_active = -1;
+ strobo_time = read_processor_time() + vsynctimebase * ratio / 100;
+ timeSetEvent(waitms, 0, blackinsertion_cb, NULL, TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
+ }
#if 0
if (ap->gfx_vsync < 0 && ap->gfx_strobo && currprefs.gfx_api < 2) {
float vblank = vblank_hz;
}
#endif
D3D_showframe(monid);
- if (monid == 0)
+ if (monid == 0) {
strobo_active2 = true;
+ if (strobo_active < 0) {
+ D3D_showframe_special(0, 2);
+ }
+ }
#ifdef GFXFILTER
} else if (mon->currentmode.flags & DM_SWSCALE) {
if (!dx_islost () && !ad->picasso_on)
flushymin = mon->currentmode.amiga_height;
flushymax = 0;
#endif
+ gfx_lock();
ret = 1;
if (mon->currentmode.flags & DM_D3D) {
#ifdef D3D
} else if (mon->currentmode.flags & DM_DDRAW) {
ret = ddraw_dolock() != 0;
}
+ gfx_unlock();
return ret;
}
void unlockscr(struct vidbuffer *vb, int y_start, int y_end)
{
struct AmigaMonitor *mon = &AMonitors[vb->monitor_id];
+ gfx_lock();
if (mon->currentmode.flags & DM_D3D) {
if (mon->currentmode.flags & DM_SWSCALE) {
S2X_render(vb->monitor_id, y_start, y_end);
DirectDraw_SurfaceUnlock();
vb->bufmem = NULL;
}
+ gfx_unlock();
}
void flush_clear_screen (struct vidbuffer *vb)
{07609D0D-FE6B-4A84-8C87-F914A4566F6F}.Test|Mixed Platforms.ActiveCfg = Release|Win32
{07609D0D-FE6B-4A84-8C87-F914A4566F6F}.Test|Mixed Platforms.Build.0 = Release|Win32
{07609D0D-FE6B-4A84-8C87-F914A4566F6F}.Test|Win32.ActiveCfg = Release|Win32
- {07609D0D-FE6B-4A84-8C87-F914A4566F6F}.Test|Win32.Build.0 = Release|Win32
{07609D0D-FE6B-4A84-8C87-F914A4566F6F}.Test|x64.ActiveCfg = Release|x64
{07609D0D-FE6B-4A84-8C87-F914A4566F6F}.Test|x64.Build.0 = Release|x64
EndGlobalSection
int framesize;
uae_u8 io[256];
uae_u16 wordlatch;
+ int timer_cnt;
+ int timer_event_time;
+ int timer_active;
int sample[MAX_UAE_CHANNELS];
};
struct uaesndboard_data
24.W volume (0 to 32768)
26.L next sample set address (0=end, this was last set)
32.B number of channels. (interleaved samples if 2 or more channels)
- 33.B sample type (bit 0: bits per sample, 0=8,1=16, bit 6=signed, bit 7=little-endian)
+ 33.B sample type (bit 0: bits per sample, 0=8,1=16,2=24,3=32 bit 6=signed, bit 7=little-endian)
34.B bit 0: interrupt when set starts, bit 1: interrupt when set ends (last sample played), bit 2: interrupt when repeat starts, bit 3: after each sample.
35.B if mono stream, bit mask that selects output channels. (0=default, redirect to left and right channels)
(Can be used for example when playing tracker modules by using 4 single channel streams)
$0184.B Reserved
$0185.B Reserved
$0186.B Reserved
- $0187.B Interrupt status. 7: set when interrupt active. 0,1,2,3: same as 30.B bit, always set when condition matches,
- even if 30.B bit is not set. If also 30.B bit is set: bit 7 set and interrupt is activated.
+ $0187.B Interrupt status. 7: set when interrupt active. 0,1,2,3: same as 34.B bit, always set when condition matches,
+ even if 34.B bit is not set. If also 34.B bit is set: bit 7 set and interrupt is activated.
+ bit 4 = timer interrupt.
Reading clears interrupt. RO.
$0188.B Reserved
$0189.B Reserved
$018A.B Reserved
$018B.B Alternate interrupt status. Same as $187.B but reading does not clear interrupt. RO.
+ $0190.B Stream master interrupt enable (same bits as $0187.B)
+ $0190.L Timer frequency (same format as 12.L), sets interrupt bit 4. Zero = disabled. WO.
$0200 stream 2
68020+ aligned long accesses are always guaranteed safe.
Set structure is copied to emulator side internal address space when set starts.
- This data can be always read and written in real time by accessing $0100-$011f space.
+ This data can be always read and written in real time by accessing $0100-$013f space.
Writes are nearly immediate, values are updated during next sample period.
(It probably is not a good idea to do on the fly change number of channels or bits per sample values..)
Hardware word and long accesses must be aligned (unaligned write is ignored, unaligned read will return 0xffff or 0xffffffff)
+ Timer is usable when stream is allocated. Active audio play is not required.
+
*/
#define STREAM_STRUCT_SIZE 40
static void uaesnd_irq(struct uaesndboard_stream *s, uae_u8 mask)
{
+ uae_u8 enablemask = get_long_host(s->io + 0x90);
+ uae_u8 intenamask = s->intenamask | 0x10 | 0x20 | 0x40;
s->intreqmask |= mask;
- if ((s->intenamask & mask)) {
+ if ((intenamask & mask) && (enablemask & mask)) {
s->intreqmask |= 0x80;
devices_rethink_all(sndboard_rethink);
}
len = s->repeating ? s->replen : s->len;
addr = s->repeating ? s->repeat : s->address;
}
- bool bit16 = (s->bitmode & 1) != 0;
+ int st = (s->bitmode & 7);
bool le = (s->bitmode & 0x80) != 0;
bool sign = (s->bitmode & 0x40) != 0;
bool len_nonzero = len != 0;
addr -= s->framesize;
for (int i = 0; i < s->ch; i++) {
uae_u16 sample = 0;
- if (bit16) {
+ switch (st)
+ {
+ case 3: // 32-bit (last 2 bytes ignored)
+ sample = get_word(le ? (addr + 2) : (addr + 0));
+ addr += 4;
+ break;
+ case 2: // 24-bit (last byte ignored)
+ sample = get_word(le ? (addr + 1) : (addr + 0));
+ addr += 3;
+ break;
+ case 1: // 16-bit
sample = get_word(addr);
- if (le)
- sample = (sample >> 8) | (sample << 8);
addr += 2;
- } else {
+ break;
+ case 0: // 8-bit
sample = get_byte(addr);
sample = (sample << 8) | sample;
addr += 1;
+ break;
}
+ if (le)
+ sample = (sample >> 8) | (sample << 8);
if (sign)
sample -= 0x8000;
uae_s16 samples = (uae_s16)sample;
}
}
+static int uaesnd_timer_period(uae_u32 v)
+{
+ if ((v >> 16) == 0xffff) {
+ return v & 65535;
+ } else {
+ return (uae_s64)base_event_clock * CYCLE_UNIT * 256 / v;
+ }
+}
+
+static void uaesnd_timer(uae_u32 v)
+{
+ struct uaesndboard_data *data = &uaesndboard[v >> 16];
+ struct uaesndboard_stream *s = &data->stream[v & 65535];
+ s->timer_cnt = get_long_host(s->io + 0x90);
+ if (s->timer_cnt > 0 && data->enabled) {
+ s->timer_event_time = uaesnd_timer_period(s->timer_cnt);
+ if (s->timer_event_time > 0) {
+ event2_newevent_xx(-1, s->timer_event_time, s - &data->stream[0], uaesnd_timer);
+ uaesnd_irq(s, 0x10);
+ s->timer_active = 1;
+ }
+ } else {
+ s->timer_active = 0;
+ }
+}
+
static void uaesnd_put(struct uaesndboard_data *data, struct uaesndboard_stream *s, int reg)
{
if (reg == 0x80) { // set pointer write?
uaecptr setaddr = get_long_host(s->io + 0x80);
s->next = setaddr;
uaesnd_stream_start(data, s);
+ } else if (reg == 0x90) { // timer
+ s->timer_cnt = get_long_host(s->io + 0x90);
+ if (s->timer_cnt > 0 && !s->timer_active) {
+ s->timer_event_time = uaesnd_timer_period(s->timer_cnt);
+ if (s->timer_event_time > 0) {
+ s->timer_active = 1;
+ event2_newevent_xx(-1, s->timer_event_time, ((data - &uaesndboard[0]) << 16) | (s - &data->stream[0]), uaesnd_timer);
+ }
+ }
} else {
if (!uaesnd_directload(s, reg)) {
uaesndboard_stop(data, s);