mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-06-13 02:29:40 +00:00
Manual merge from master @ c798157
This commit is contained in:
parent
0cc6a4841f
commit
e98de27039
|
@ -76,16 +76,19 @@
|
||||||
<ClInclude Include="source\NoSlotClock.h" />
|
<ClInclude Include="source\NoSlotClock.h" />
|
||||||
<ClInclude Include="source\NTSC.h" />
|
<ClInclude Include="source\NTSC.h" />
|
||||||
<ClInclude Include="source\ParallelPrinter.h" />
|
<ClInclude Include="source\ParallelPrinter.h" />
|
||||||
|
<ClInclude Include="source\Pravets.h" />
|
||||||
<ClInclude Include="source\Registry.h" />
|
<ClInclude Include="source\Registry.h" />
|
||||||
<ClInclude Include="source\Riff.h" />
|
<ClInclude Include="source\Riff.h" />
|
||||||
|
<ClInclude Include="source\SAM.h" />
|
||||||
<ClInclude Include="source\SaveState.h" />
|
<ClInclude Include="source\SaveState.h" />
|
||||||
|
<ClInclude Include="source\SaveState_Structs_common.h" />
|
||||||
|
<ClInclude Include="source\SaveState_Structs_v1.h" />
|
||||||
<ClInclude Include="source\SerialComms.h" />
|
<ClInclude Include="source\SerialComms.h" />
|
||||||
<ClInclude Include="source\SoundCore.h" />
|
<ClInclude Include="source\SoundCore.h" />
|
||||||
<ClInclude Include="source\Speaker.h" />
|
<ClInclude Include="source\Speaker.h" />
|
||||||
<ClInclude Include="source\Speech.h" />
|
<ClInclude Include="source\Speech.h" />
|
||||||
<ClInclude Include="source\SSI263Phonemes.h" />
|
<ClInclude Include="source\SSI263Phonemes.h" />
|
||||||
<ClInclude Include="source\StdAfx.h" />
|
<ClInclude Include="source\StdAfx.h" />
|
||||||
<ClInclude Include="source\Structs.h" />
|
|
||||||
<ClInclude Include="source\Tape.h" />
|
<ClInclude Include="source\Tape.h" />
|
||||||
<ClInclude Include="source\Tfe\Bittypes.h" />
|
<ClInclude Include="source\Tfe\Bittypes.h" />
|
||||||
<ClInclude Include="source\Tfe\Bpf.h" />
|
<ClInclude Include="source\Tfe\Bpf.h" />
|
||||||
|
@ -97,6 +100,7 @@
|
||||||
<ClInclude Include="source\Tfe\Tfesupp.h" />
|
<ClInclude Include="source\Tfe\Tfesupp.h" />
|
||||||
<ClInclude Include="source\Tfe\Uilib.h" />
|
<ClInclude Include="source\Tfe\Uilib.h" />
|
||||||
<ClInclude Include="source\Video.h" />
|
<ClInclude Include="source\Video.h" />
|
||||||
|
<ClInclude Include="source\YamlHelper.h" />
|
||||||
<ClInclude Include="source\z80emu.h" />
|
<ClInclude Include="source\z80emu.h" />
|
||||||
<ClInclude Include="source\Z80VICE\daa.h" />
|
<ClInclude Include="source\Z80VICE\daa.h" />
|
||||||
<ClInclude Include="source\Z80VICE\z80.h" />
|
<ClInclude Include="source\Z80VICE\z80.h" />
|
||||||
|
@ -107,7 +111,7 @@
|
||||||
<Text Include="docs\CodingConventions.txt" />
|
<Text Include="docs\CodingConventions.txt" />
|
||||||
<Text Include="docs\Debugger_Changelog.txt" />
|
<Text Include="docs\Debugger_Changelog.txt" />
|
||||||
<Text Include="docs\FAQ.txt" />
|
<Text Include="docs\FAQ.txt" />
|
||||||
<Text Include="docs\History.txt" />
|
<Text Include="bin\History.txt" />
|
||||||
<Text Include="docs\ToDo.txt" />
|
<Text Include="docs\ToDo.txt" />
|
||||||
<Text Include="docs\Video_Cleanup.txt" />
|
<Text Include="docs\Video_Cleanup.txt" />
|
||||||
<Text Include="docs\Wishlist.txt" />
|
<Text Include="docs\Wishlist.txt" />
|
||||||
|
@ -126,6 +130,7 @@
|
||||||
<ClCompile Include="source\Configuration\PropertySheet.cpp" />
|
<ClCompile Include="source\Configuration\PropertySheet.cpp" />
|
||||||
<ClCompile Include="source\Configuration\PropertySheetHelper.cpp" />
|
<ClCompile Include="source\Configuration\PropertySheetHelper.cpp" />
|
||||||
<ClCompile Include="source\CPU.cpp" />
|
<ClCompile Include="source\CPU.cpp" />
|
||||||
|
<ClCompile Include="source\SAM.cpp" />
|
||||||
<ClCompile Include="source\Debugger\Debug.cpp" />
|
<ClCompile Include="source\Debugger\Debug.cpp" />
|
||||||
<ClCompile Include="source\Debugger\Debugger_Assembler.cpp" />
|
<ClCompile Include="source\Debugger\Debugger_Assembler.cpp" />
|
||||||
<ClCompile Include="source\Debugger\Debugger_Color.cpp" />
|
<ClCompile Include="source\Debugger\Debugger_Color.cpp" />
|
||||||
|
@ -152,6 +157,7 @@
|
||||||
<ClCompile Include="source\NoSlotClock.cpp" />
|
<ClCompile Include="source\NoSlotClock.cpp" />
|
||||||
<ClCompile Include="source\NTSC.cpp" />
|
<ClCompile Include="source\NTSC.cpp" />
|
||||||
<ClCompile Include="source\ParallelPrinter.cpp" />
|
<ClCompile Include="source\ParallelPrinter.cpp" />
|
||||||
|
<ClCompile Include="source\Pravets.cpp" />
|
||||||
<ClCompile Include="source\Registry.cpp" />
|
<ClCompile Include="source\Registry.cpp" />
|
||||||
<ClCompile Include="source\Riff.cpp" />
|
<ClCompile Include="source\Riff.cpp" />
|
||||||
<ClCompile Include="source\SaveState.cpp" />
|
<ClCompile Include="source\SaveState.cpp" />
|
||||||
|
@ -191,6 +197,7 @@
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release NoDX|Win32'">NotUsing</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release NoDX|Win32'">NotUsing</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="source\Video.cpp" />
|
<ClCompile Include="source\Video.cpp" />
|
||||||
|
<ClCompile Include="source\YamlHelper.cpp" />
|
||||||
<ClCompile Include="source\z80emu.cpp" />
|
<ClCompile Include="source\z80emu.cpp" />
|
||||||
<ClCompile Include="source\Z80VICE\daa.cpp">
|
<ClCompile Include="source\Z80VICE\daa.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
@ -237,6 +244,9 @@
|
||||||
<ProjectReference Include="zlib\zlib-Express2013.vcxproj">
|
<ProjectReference Include="zlib\zlib-Express2013.vcxproj">
|
||||||
<Project>{9b32a6e7-1237-4f36-8903-a3fd51df9c4e}</Project>
|
<Project>{9b32a6e7-1237-4f36-8903-a3fd51df9c4e}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="libyaml\win32\yaml2013.vcxproj">
|
||||||
|
<Project>{0212e0df-06da-4080-bd1d-f3b01599f70f}</Project>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="resource\Applewin.bmp" />
|
<Image Include="resource\Applewin.bmp" />
|
||||||
|
@ -343,9 +353,9 @@
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;YAML_DECLARE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>source\cpu;source\emulator;source\debugger;zlib;zip_lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
|
@ -354,15 +364,22 @@
|
||||||
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;ddraw.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;Advapi32.lib;shell32.lib;Comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;ddraw.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;Advapi32.lib;shell32.lib;Comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>echo Performing unit-test: TestCPU6502
|
||||||
|
.\Debug\TestCPU6502.exe</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Message>Performing unit-test: TestCPU6502</Message>
|
||||||
|
</PreBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug NoDX|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug NoDX|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;NO_DIRECT_X;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;NO_DIRECT_X;YAML_DECLARE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>source\cpu;source\emulator;source\debugger;zlib;zip_lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
|
@ -371,6 +388,13 @@
|
||||||
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;ddraw.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;Advapi32.lib;shell32.lib;Comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;ddraw.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;Advapi32.lib;shell32.lib;Comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>echo Performing unit-test: TestCPU6502
|
||||||
|
.\Debug\TestCPU6502.exe</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Message>Performing unit-test: TestCPU6502</Message>
|
||||||
|
</PreBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -379,9 +403,9 @@
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;YAML_DECLARE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>source\cpu;source\emulator;source\debugger;zlib;zip_lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -394,6 +418,13 @@
|
||||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>echo Performing unit-test: TestCPU6502
|
||||||
|
.\Release\TestCPU6502.exe</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Message>Performing unit-test: TestCPU6502</Message>
|
||||||
|
</PreBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release NoDX|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release NoDX|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -402,9 +433,9 @@
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;NO_DIRECT_X;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;NO_DIRECT_X;YAML_DECLARE_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>source\cpu;source\emulator;source\debugger;zlib;zip_lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -417,6 +448,13 @@
|
||||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>echo Performing unit-test: TestCPU6502
|
||||||
|
.\Release\TestCPU6502.exe</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Message>Performing unit-test: TestCPU6502</Message>
|
||||||
|
</PreBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
@ -172,6 +172,15 @@
|
||||||
<ClCompile Include="source\NTSC.cpp">
|
<ClCompile Include="source\NTSC.cpp">
|
||||||
<Filter>Source Files\Video</Filter>
|
<Filter>Source Files\Video</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="source\Pravets.cpp">
|
||||||
|
<Filter>Source Files\Model</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="source\SAM.cpp">
|
||||||
|
<Filter>Source Files\Emulator</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="source\YamlHelper.cpp">
|
||||||
|
<Filter>Source Files\Emulator</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="source\Applewin.h">
|
<ClInclude Include="source\Applewin.h">
|
||||||
|
@ -372,9 +381,6 @@
|
||||||
<ClInclude Include="source\StdAfx.h">
|
<ClInclude Include="source\StdAfx.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="source\Structs.h">
|
|
||||||
<Filter>Source Files\_Headers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="source\Tape.h">
|
<ClInclude Include="source\Tape.h">
|
||||||
<Filter>Source Files\Emulator</Filter>
|
<Filter>Source Files\Emulator</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -423,6 +429,21 @@
|
||||||
<ClInclude Include="source\NTSC.h">
|
<ClInclude Include="source\NTSC.h">
|
||||||
<Filter>Source Files\Video</Filter>
|
<Filter>Source Files\Video</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="source\Pravets.h">
|
||||||
|
<Filter>Source Files\Model</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="source\SAM.h">
|
||||||
|
<Filter>Source Files\Emulator</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="source\YamlHelper.h">
|
||||||
|
<Filter>Source Files\Emulator</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="source\SaveState_Structs_common.h">
|
||||||
|
<Filter>Source Files\_Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="source\SaveState_Structs_v1.h">
|
||||||
|
<Filter>Source Files\_Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="resource\Applewin.bmp">
|
<Image Include="resource\Applewin.bmp">
|
||||||
|
@ -591,9 +612,6 @@
|
||||||
<Text Include="docs\FAQ.txt">
|
<Text Include="docs\FAQ.txt">
|
||||||
<Filter>Docs</Filter>
|
<Filter>Docs</Filter>
|
||||||
</Text>
|
</Text>
|
||||||
<Text Include="docs\History.txt">
|
|
||||||
<Filter>Docs</Filter>
|
|
||||||
</Text>
|
|
||||||
<Text Include="docs\ToDo.txt">
|
<Text Include="docs\ToDo.txt">
|
||||||
<Filter>Docs</Filter>
|
<Filter>Docs</Filter>
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -603,6 +621,7 @@
|
||||||
<Text Include="docs\Wishlist.txt">
|
<Text Include="docs\Wishlist.txt">
|
||||||
<Filter>Docs</Filter>
|
<Filter>Docs</Filter>
|
||||||
</Text>
|
</Text>
|
||||||
|
<Text Include="bin\History.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Docs">
|
<Filter Include="Docs">
|
||||||
|
@ -644,6 +663,9 @@
|
||||||
<Filter Include="Resource Files">
|
<Filter Include="Resource Files">
|
||||||
<UniqueIdentifier>{b5c6889e-727d-4339-96c8-e4284e1d6e0f}</UniqueIdentifier>
|
<UniqueIdentifier>{b5c6889e-727d-4339-96c8-e4284e1d6e0f}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Source Files\Model">
|
||||||
|
<UniqueIdentifier>{15b450e4-f89f-4d80-9c44-48b32f33f3e3}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="resource\Applewin.rc">
|
<ResourceCompile Include="resource\Applewin.rc">
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCPreBuildEventTool"
|
Name="VCPreBuildEventTool"
|
||||||
|
Description="Performing unit-test: TestCPU6502"
|
||||||
|
CommandLine=".\Release\TestCPU6502.exe"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
|
@ -54,8 +56,8 @@
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="true"
|
||||||
AdditionalIncludeDirectories="source\cpu;source\emulator;source\debugger;zlib;zip_lib"
|
AdditionalIncludeDirectories="source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;YAML_DECLARE_STATIC"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
|
@ -130,6 +132,8 @@
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCPreBuildEventTool"
|
Name="VCPreBuildEventTool"
|
||||||
|
Description="Performing unit-test: TestCPU6502"
|
||||||
|
CommandLine=".\Debug\TestCPU6502.exe"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
|
@ -153,8 +157,8 @@
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalOptions="/Zm200 "
|
AdditionalOptions="/Zm200 "
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="source\cpu;source\emulator;source\debugger;zlib;zip_lib"
|
AdditionalIncludeDirectories="source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;YAML_DECLARE_STATIC"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
UsePrecompiledHeader="2"
|
UsePrecompiledHeader="2"
|
||||||
|
@ -686,6 +690,14 @@
|
||||||
RelativePath=".\source\Riff.h"
|
RelativePath=".\source\Riff.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\SAM.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\SAM.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\SaveState.cpp"
|
RelativePath=".\source\SaveState.cpp"
|
||||||
>
|
>
|
||||||
|
@ -734,6 +746,14 @@
|
||||||
RelativePath=".\source\Tape.h"
|
RelativePath=".\source\Tape.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\YamlHelper.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\YamlHelper.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\z80emu.cpp"
|
RelativePath=".\source\z80emu.cpp"
|
||||||
>
|
>
|
||||||
|
@ -755,11 +775,15 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\SSI263Phonemes.h"
|
RelativePath=".\source\SaveState_Structs_common.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\source\Structs.h"
|
RelativePath=".\source\SaveState_Structs_v1.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\SSI263Phonemes.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
@ -959,6 +983,18 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Model"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\Pravets.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\Pravets.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Docs"
|
Name="Docs"
|
||||||
|
|
BIN
Disks/SAM Slot 5.dsk
Normal file
BIN
Disks/SAM Slot 5.dsk
Normal file
Binary file not shown.
|
@ -9,6 +9,12 @@ https://github.com/AppleWin/AppleWin/issues/new
|
||||||
Tom Charlesworth
|
Tom Charlesworth
|
||||||
|
|
||||||
|
|
||||||
|
1.25.0.4 - 23 Apr 2015
|
||||||
|
----------------------
|
||||||
|
Fixes:
|
||||||
|
. [Bug #276] -d1 command line argument caused AppleWin to quickly exit.
|
||||||
|
|
||||||
|
|
||||||
1.25.0.3 - 8 Sep 2014
|
1.25.0.3 - 8 Sep 2014
|
||||||
---------------------
|
---------------------
|
||||||
Note: This is the last planned version to support Win98/ME.
|
Note: This is the last planned version to support Win98/ME.
|
||||||
|
|
|
@ -154,10 +154,11 @@ BEGIN
|
||||||
CONTROL "Slider1",IDC_SPKR_VOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_VERT | TBS_BOTH | WS_TABSTOP,13,47,28,60
|
CONTROL "Slider1",IDC_SPKR_VOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_VERT | TBS_BOTH | WS_TABSTOP,13,47,28,60
|
||||||
LTEXT "&Mockingboard:",IDC_STATIC,49,39,51,8
|
LTEXT "&Mockingboard:",IDC_STATIC,49,39,51,8
|
||||||
CONTROL "Slider1",IDC_MB_VOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_VERT | TBS_BOTH | WS_TABSTOP,59,47,25,60
|
CONTROL "Slider1",IDC_MB_VOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_VERT | TBS_BOTH | WS_TABSTOP,59,47,25,60
|
||||||
GROUPBOX "Sound Cards",IDC_STATIC,6,122,197,61
|
GROUPBOX "Sound Cards",IDC_STATIC,6,122,197,64
|
||||||
CONTROL "Mockingboards (in slots 4 && 5)",IDC_MB_ENABLE,"Button",BS_AUTORADIOBUTTON,10,136,142,8
|
CONTROL "Mockingboards (in slots 4 && 5)",IDC_MB_ENABLE,"Button",BS_AUTORADIOBUTTON,10,136,142,8
|
||||||
CONTROL "Phasor (in slot 4)",IDC_PHASOR_ENABLE,"Button",BS_AUTORADIOBUTTON,10,149,92,10
|
CONTROL "Phasor (in slot 4)",IDC_PHASOR_ENABLE,"Button",BS_AUTORADIOBUTTON,10,149,92,10
|
||||||
CONTROL "No sound cards",IDC_SOUNDCARD_DISABLE,"Button",BS_AUTORADIOBUTTON,10,163,78,10
|
CONTROL "SAM/DAC (in slot 5)",IDC_SAM_ENABLE,"Button",BS_AUTORADIOBUTTON,10,162,95,10
|
||||||
|
CONTROL "No sound cards",IDC_SOUNDCARD_DISABLE,"Button",BS_AUTORADIOBUTTON,10,175,78,10
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_PROPPAGE_DISK DIALOGEX 0, 0, 211, 188
|
IDD_PROPPAGE_DISK DIALOGEX 0, 0, 211, 188
|
||||||
|
@ -270,7 +271,7 @@ BEGIN
|
||||||
VALUE "FileDescription", "Apple //e Emulator for Windows"
|
VALUE "FileDescription", "Apple //e Emulator for Windows"
|
||||||
VALUE "FileVersion", "1.26.0.0"
|
VALUE "FileVersion", "1.26.0.0"
|
||||||
VALUE "InternalName", "APPLEWIN"
|
VALUE "InternalName", "APPLEWIN"
|
||||||
VALUE "LegalCopyright", " 1994-2014 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis"
|
VALUE "LegalCopyright", " 1994-2015 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis"
|
||||||
VALUE "OriginalFilename", "APPLEWIN.EXE"
|
VALUE "OriginalFilename", "APPLEWIN.EXE"
|
||||||
VALUE "ProductName", "Apple //e Emulator"
|
VALUE "ProductName", "Apple //e Emulator"
|
||||||
VALUE "ProductVersion", "1.26.0.0 Alpha"
|
VALUE "ProductVersion", "1.26.0.0 Alpha"
|
||||||
|
|
|
@ -67,36 +67,39 @@
|
||||||
#define IDC_SPIN_XTRIM 1026
|
#define IDC_SPIN_XTRIM 1026
|
||||||
#define IDC_SPIN_YTRIM 1027
|
#define IDC_SPIN_YTRIM 1027
|
||||||
#define IDC_PHASOR_ENABLE 1029
|
#define IDC_PHASOR_ENABLE 1029
|
||||||
#define IDC_SOUNDCARD_DISABLE 1030
|
#define IDC_SAM_ENABLE 1030
|
||||||
#define IDC_TFE_SETTINGS_ENABLE_T 1031
|
#define IDC_SOUNDCARD_DISABLE 1031
|
||||||
#define IDC_TFE_SETTINGS_ENABLE 1032
|
|
||||||
#define IDC_TFE_SETTINGS_INTERFACE_T 1033
|
#define IDC_TFE_SETTINGS_ENABLE_T 1032
|
||||||
#define IDC_TFE_SETTINGS_INTERFACE 1034
|
#define IDC_TFE_SETTINGS_ENABLE 1033
|
||||||
#define IDC_TFE_SETTINGS_INTERFACE_NAME 1035
|
#define IDC_TFE_SETTINGS_INTERFACE_T 1034
|
||||||
#define IDC_TFE_SETTINGS_INTERFACE_DESC 1036
|
#define IDC_TFE_SETTINGS_INTERFACE 1035
|
||||||
#define IDS_TFE_CAPTION 1037
|
#define IDC_TFE_SETTINGS_INTERFACE_NAME 1036
|
||||||
#define IDS_TFE_ETHERNET 1038
|
#define IDC_TFE_SETTINGS_INTERFACE_DESC 1037
|
||||||
#define IDS_TFE_INTERFACE 1039
|
#define IDS_TFE_CAPTION 1038
|
||||||
#define IDS_OK 1040
|
#define IDS_TFE_ETHERNET 1039
|
||||||
#define IDS_CANCEL 1041
|
#define IDS_TFE_INTERFACE 1040
|
||||||
#define IDC_ETHERNET 1042
|
#define IDS_OK 1041
|
||||||
#define IDC_SCROLLLOCK_TOGGLE 1043
|
#define IDS_CANCEL 1042
|
||||||
#define IDC_MOUSE_IN_SLOT4 1044
|
#define IDC_ETHERNET 1043
|
||||||
#define IDC_THE_FREEZES_F8_ROM_FW 1045
|
#define IDC_SCROLLLOCK_TOGGLE 1044
|
||||||
#define IDC_MOUSE_CROSSHAIR 1046
|
#define IDC_MOUSE_IN_SLOT4 1045
|
||||||
#define IDC_CLONETYPE 1047
|
#define IDC_THE_FREEZES_F8_ROM_FW 1046
|
||||||
#define IDC_MOUSE_RESTRICT_TO_WINDOW 1048
|
#define IDC_MOUSE_CROSSHAIR 1047
|
||||||
#define IDC_CIDERPRESS_BROWSE 1049
|
#define IDC_CLONETYPE 1048
|
||||||
#define IDC_CIDERPRESS_FILENAME 1050
|
#define IDC_MOUSE_RESTRICT_TO_WINDOW 1049
|
||||||
#define IDC_CPM_CONFIG 1051
|
#define IDC_CIDERPRESS_BROWSE 1050
|
||||||
#define IDC_DUMPTOPRINTER 1052
|
#define IDC_CIDERPRESS_FILENAME 1051
|
||||||
#define IDC_PRINTER_DUMP_FILENAME 1053
|
#define IDC_CPM_CONFIG 1052
|
||||||
#define IDC_PRINTER_DUMP_FILENAME_BROWSE 1054
|
#define IDC_DUMPTOPRINTER 1053
|
||||||
#define IDC_PRINTER_CONVERT_ENCODING 1055
|
#define IDC_PRINTER_DUMP_FILENAME 1054
|
||||||
#define IDC_PRINTER_FILTER_UNPRINTABLE 1056
|
#define IDC_PRINTER_DUMP_FILENAME_BROWSE 1055
|
||||||
#define IDC_PRINTER_APPEND 1057
|
#define IDC_PRINTER_CONVERT_ENCODING 1056
|
||||||
#define IDC_SPIN_PRINTER_IDLE 1058
|
#define IDC_PRINTER_FILTER_UNPRINTABLE 1057
|
||||||
#define IDC_CHECK_HALF_SCAN_LINES 1059
|
#define IDC_PRINTER_APPEND 1058
|
||||||
|
#define IDC_SPIN_PRINTER_IDLE 1059
|
||||||
|
|
||||||
|
#define IDC_CHECK_HALF_SCAN_LINES 1060
|
||||||
#define IDC_GPL_TEXT 1061
|
#define IDC_GPL_TEXT 1061
|
||||||
#define IDC_GPL_BORDER 1063
|
#define IDC_GPL_BORDER 1063
|
||||||
#define IDC_APPLEWIN_VERSION 1064
|
#define IDC_APPLEWIN_VERSION 1064
|
||||||
|
|
|
@ -32,6 +32,21 @@ typedef struct
|
||||||
mem_write_handler func;
|
mem_write_handler func;
|
||||||
} STWriteHandler;
|
} STWriteHandler;
|
||||||
|
|
||||||
|
struct mc6821_s {
|
||||||
|
/* MC6821 register. */
|
||||||
|
BYTE pra;
|
||||||
|
BYTE ddra;
|
||||||
|
BYTE cra;
|
||||||
|
BYTE prb;
|
||||||
|
BYTE ddrb;
|
||||||
|
BYTE crb;
|
||||||
|
|
||||||
|
/* Drive structure */
|
||||||
|
// struct drive_s *drive;
|
||||||
|
};
|
||||||
|
typedef struct mc6821_s mc6821_t;
|
||||||
|
|
||||||
|
|
||||||
class C6821
|
class C6821
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -64,6 +79,18 @@ public:
|
||||||
m_stOutB.objTo = objTo;
|
m_stOutB.objTo = objTo;
|
||||||
m_stOutB.func = func;
|
m_stOutB.func = func;
|
||||||
}
|
}
|
||||||
|
void Get6821(mc6821_t& r6821, BYTE& byIA, BYTE& byIB)
|
||||||
|
{
|
||||||
|
r6821 = mc6821[0];
|
||||||
|
byIA = m_byIA;
|
||||||
|
byIB = m_byIB;
|
||||||
|
}
|
||||||
|
void Set6821(const mc6821_t& r6821, const BYTE byIA, const BYTE byIB)
|
||||||
|
{
|
||||||
|
mc6821[0] = r6821;
|
||||||
|
m_byIA = byIA;
|
||||||
|
m_byIB = byIB;
|
||||||
|
}
|
||||||
// AppleWin:TC END
|
// AppleWin:TC END
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -75,20 +102,6 @@ private:
|
||||||
|
|
||||||
//struct drive_s;
|
//struct drive_s;
|
||||||
|
|
||||||
struct mc6821_s {
|
|
||||||
/* MC6821 register. */
|
|
||||||
BYTE pra;
|
|
||||||
BYTE ddra;
|
|
||||||
BYTE cra;
|
|
||||||
BYTE prb;
|
|
||||||
BYTE ddrb;
|
|
||||||
BYTE crb;
|
|
||||||
|
|
||||||
/* Drive structure */
|
|
||||||
// struct drive_s *drive;
|
|
||||||
};
|
|
||||||
typedef struct mc6821_s mc6821_t;
|
|
||||||
|
|
||||||
//struct drive_context_s;
|
//struct drive_context_s;
|
||||||
void mc6821_init(/*struct drive_context_s *drv*/);
|
void mc6821_init(/*struct drive_context_s *drv*/);
|
||||||
void mc6821_reset(/*struct drive_context_s *drv*/);
|
void mc6821_reset(/*struct drive_context_s *drv*/);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "Applewin.h" // For g_fh
|
#include "Applewin.h" // For g_fh
|
||||||
#include "Mockingboard.h" // For g_uTimer1IrqCount
|
#include "Mockingboard.h" // For g_uTimer1IrqCount
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
/* The AY white noise RNG algorithm is based on info from MAME's ay8910.c -
|
/* The AY white noise RNG algorithm is based on info from MAME's ay8910.c -
|
||||||
* MAME's licence explicitly permits free use of info (even encourages it).
|
* MAME's licence explicitly permits free use of info (even encourages it).
|
||||||
|
@ -114,12 +115,17 @@ static int rstereopos, rchan1pos, rchan2pos, rchan3pos;
|
||||||
double CAY8910::m_fCurrentCLK_AY8910 = 0.0;
|
double CAY8910::m_fCurrentCLK_AY8910 = 0.0;
|
||||||
|
|
||||||
|
|
||||||
CAY8910::CAY8910() :
|
void CAY8910::init(void)
|
||||||
// Init the statics that were in sound_ay_overlay()
|
|
||||||
rng(1),
|
|
||||||
noise_toggle(0),
|
|
||||||
env_first(1), env_rev(0), env_counter(15)
|
|
||||||
{
|
{
|
||||||
|
// Init the statics that were in sound_ay_overlay()
|
||||||
|
rng = 1;
|
||||||
|
noise_toggle = 0;
|
||||||
|
env_first = 1; env_rev = 0; env_counter = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAY8910::CAY8910(void)
|
||||||
|
{
|
||||||
|
init();
|
||||||
m_fCurrentCLK_AY8910 = g_fCurrentCLK6502;
|
m_fCurrentCLK_AY8910 = g_fCurrentCLK6502;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -731,6 +737,8 @@ void CAY8910::sound_ay_reset( void )
|
||||||
{
|
{
|
||||||
int f;
|
int f;
|
||||||
|
|
||||||
|
init(); // AppleWin:TC
|
||||||
|
|
||||||
/* recalculate timings based on new machines ay clock */
|
/* recalculate timings based on new machines ay clock */
|
||||||
sound_ay_init();
|
sound_ay_init();
|
||||||
|
|
||||||
|
@ -940,6 +948,192 @@ sound_beeper( int is_tape, int on )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_AY8910 "AY8910"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_TONE0_TICK "Tone0 Tick"
|
||||||
|
#define SS_YAML_KEY_TONE1_TICK "Tone1 Tick"
|
||||||
|
#define SS_YAML_KEY_TONE2_TICK "Tone2 Tick"
|
||||||
|
#define SS_YAML_KEY_TONE0_HIGH "Tone0 High"
|
||||||
|
#define SS_YAML_KEY_TONE1_HIGH "Tone1 High"
|
||||||
|
#define SS_YAML_KEY_TONE2_HIGH "Tone2 High"
|
||||||
|
#define SS_YAML_KEY_NOISE_TICK "Noise Tick"
|
||||||
|
#define SS_YAML_KEY_TONE_SUBCYCLES "Tone Subcycles"
|
||||||
|
#define SS_YAML_KEY_ENV_SUBCYCLES "Env Subcycles"
|
||||||
|
#define SS_YAML_KEY_ENV_INTERNAL_TICK "Env Internal Tick"
|
||||||
|
#define SS_YAML_KEY_ENV_TICK "Env Tick"
|
||||||
|
#define SS_YAML_KEY_TICK_INCR "Tick Incr"
|
||||||
|
#define SS_YAML_KEY_TONE0_PERIOD "Tone0 Period"
|
||||||
|
#define SS_YAML_KEY_TONE1_PERIOD "Tone1 Period"
|
||||||
|
#define SS_YAML_KEY_TONE2_PERIOD "Tone2 Period"
|
||||||
|
#define SS_YAML_KEY_NOISE_PERIOD "Noise Period"
|
||||||
|
#define SS_YAML_KEY_ENV_PERIOD "Env Period"
|
||||||
|
#define SS_YAML_KEY_RNG "RNG"
|
||||||
|
#define SS_YAML_KEY_NOISE_TOGGLE "Noise Toggle"
|
||||||
|
#define SS_YAML_KEY_ENV_FIRST "Env First"
|
||||||
|
#define SS_YAML_KEY_ENV_REV "Env Rev"
|
||||||
|
#define SS_YAML_KEY_ENV_COUNTER "Env Counter"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_REGISTERS "Registers"
|
||||||
|
#define SS_YAML_KEY_REG_TONE0_PERIOD "Tone0 Period"
|
||||||
|
#define SS_YAML_KEY_REG_TONE1_PERIOD "Tone1 Period"
|
||||||
|
#define SS_YAML_KEY_REG_TONE2_PERIOD "Tone2 Period"
|
||||||
|
#define SS_YAML_KEY_REG_NOISE_PERIOD "Noise Period"
|
||||||
|
#define SS_YAML_KEY_REG_MIXER "Mixer"
|
||||||
|
#define SS_YAML_KEY_REG_VOL0 "Vol0"
|
||||||
|
#define SS_YAML_KEY_REG_VOL1 "Vol1"
|
||||||
|
#define SS_YAML_KEY_REG_VOL2 "Vol2"
|
||||||
|
#define SS_YAML_KEY_REG_ENV_PERIOD "Env Period"
|
||||||
|
#define SS_YAML_KEY_REG_ENV_SHAPE "Env Shape"
|
||||||
|
#define SS_YAML_KEY_REG_PORTA "PortA"
|
||||||
|
#define SS_YAML_KEY_REG_PORTB "PortB"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_CHANGE "Change"
|
||||||
|
#define SS_YAML_VALUE_CHANGE_FORMAT "%d, %d, 0x%1X, 0x%02X"
|
||||||
|
|
||||||
|
void CAY8910::SaveSnapshot(YamlSaveHelper& yamlSaveHelper, std::string& suffix)
|
||||||
|
{
|
||||||
|
std::string unit = std::string(SS_YAML_KEY_AY8910) + suffix;
|
||||||
|
YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", unit.c_str());
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE0_TICK, ay_tone_tick[0]);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE1_TICK, ay_tone_tick[1]);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE2_TICK, ay_tone_tick[2]);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE0_HIGH, ay_tone_high[0]);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE1_HIGH, ay_tone_high[1]);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE2_HIGH, ay_tone_high[2]);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_TICK, ay_noise_tick);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE_SUBCYCLES, ay_tone_subcycles);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_SUBCYCLES, ay_env_subcycles);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_INTERNAL_TICK, ay_env_internal_tick);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_TICK, ay_env_tick);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TICK_INCR, ay_tick_incr);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE0_PERIOD, ay_tone_period[0]);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE1_PERIOD, ay_tone_period[1]);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE2_PERIOD, ay_tone_period[2]);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_PERIOD, ay_noise_period);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_RNG, rng);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_TOGGLE, noise_toggle);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_FIRST, env_first);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_REV, env_rev);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_COUNTER, env_counter);
|
||||||
|
|
||||||
|
// New label
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label registers(yamlSaveHelper, "%s:\n", SS_YAML_KEY_REGISTERS);
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveHexUint12(SS_YAML_KEY_REG_TONE0_PERIOD, (UINT)(sound_ay_registers[1]<<8) | sound_ay_registers[0]);
|
||||||
|
yamlSaveHelper.SaveHexUint12(SS_YAML_KEY_REG_TONE1_PERIOD, (UINT)(sound_ay_registers[3]<<8) | sound_ay_registers[2]);
|
||||||
|
yamlSaveHelper.SaveHexUint12(SS_YAML_KEY_REG_TONE2_PERIOD, (UINT)(sound_ay_registers[5]<<8) | sound_ay_registers[4]);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_NOISE_PERIOD, sound_ay_registers[6]);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_MIXER, sound_ay_registers[7]);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_VOL0, sound_ay_registers[8]);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_VOL1, sound_ay_registers[9]);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_VOL2, sound_ay_registers[10]);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REG_ENV_PERIOD, (UINT)(sound_ay_registers[12]<<8) | sound_ay_registers[11]);
|
||||||
|
yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_REG_ENV_SHAPE, sound_ay_registers[13]);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_PORTA, sound_ay_registers[14]);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_PORTB, sound_ay_registers[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// New label
|
||||||
|
if (ay_change_count)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label change(yamlSaveHelper, "%s:\n", SS_YAML_KEY_CHANGE);
|
||||||
|
|
||||||
|
for (int i=0; i<ay_change_count; i++)
|
||||||
|
yamlSaveHelper.Save("0x%04X: " SS_YAML_VALUE_CHANGE_FORMAT "\n", i, ay_change[i].tstates, ay_change[i].ofs, ay_change[i].reg, ay_change[i].val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAY8910::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, std::string& suffix)
|
||||||
|
{
|
||||||
|
std::string unit = std::string(SS_YAML_KEY_AY8910) + suffix;
|
||||||
|
if (!yamlLoadHelper.GetSubMap(unit))
|
||||||
|
throw std::string("Card: Expected key: ") + unit;
|
||||||
|
|
||||||
|
ay_tone_tick[0] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE0_TICK);
|
||||||
|
ay_tone_tick[1] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE1_TICK);
|
||||||
|
ay_tone_tick[2] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE2_TICK);
|
||||||
|
ay_tone_high[0] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE0_HIGH);
|
||||||
|
ay_tone_high[1] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE1_HIGH);
|
||||||
|
ay_tone_high[2] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE2_HIGH);
|
||||||
|
ay_noise_tick = yamlLoadHelper.LoadUint(SS_YAML_KEY_NOISE_TICK);
|
||||||
|
ay_tone_subcycles = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE_SUBCYCLES);
|
||||||
|
ay_env_subcycles = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_SUBCYCLES);
|
||||||
|
ay_env_internal_tick = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_INTERNAL_TICK);
|
||||||
|
ay_env_tick = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_TICK);
|
||||||
|
ay_tick_incr = yamlLoadHelper.LoadUint(SS_YAML_KEY_TICK_INCR);
|
||||||
|
ay_tone_period[0] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE0_PERIOD);
|
||||||
|
ay_tone_period[1] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE1_PERIOD);
|
||||||
|
ay_tone_period[2] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE2_PERIOD);
|
||||||
|
ay_noise_period = yamlLoadHelper.LoadUint(SS_YAML_KEY_NOISE_PERIOD);
|
||||||
|
rng = yamlLoadHelper.LoadUint(SS_YAML_KEY_RNG);
|
||||||
|
noise_toggle = yamlLoadHelper.LoadUint(SS_YAML_KEY_NOISE_TOGGLE);
|
||||||
|
env_first = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_FIRST);
|
||||||
|
env_rev = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_REV);
|
||||||
|
env_counter = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_COUNTER);
|
||||||
|
|
||||||
|
if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_REGISTERS))
|
||||||
|
throw std::string("Card: Expected key: ") + SS_YAML_KEY_REGISTERS;
|
||||||
|
|
||||||
|
USHORT period = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_TONE0_PERIOD);
|
||||||
|
sound_ay_registers[0] = period & 0xff;
|
||||||
|
sound_ay_registers[1] = (period >> 8) & 0xf;
|
||||||
|
period = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_TONE1_PERIOD);
|
||||||
|
sound_ay_registers[2] = period & 0xff;
|
||||||
|
sound_ay_registers[3] = (period >> 8) & 0xf;
|
||||||
|
period = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_TONE2_PERIOD);
|
||||||
|
sound_ay_registers[4] = period & 0xff;
|
||||||
|
sound_ay_registers[5] = (period >> 8) & 0xf;
|
||||||
|
sound_ay_registers[6] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_NOISE_PERIOD);
|
||||||
|
sound_ay_registers[7] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_MIXER);
|
||||||
|
sound_ay_registers[8] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_VOL0);
|
||||||
|
sound_ay_registers[9] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_VOL1);
|
||||||
|
sound_ay_registers[10] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_VOL2);
|
||||||
|
period = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_ENV_PERIOD);
|
||||||
|
sound_ay_registers[11] = period & 0xff;
|
||||||
|
sound_ay_registers[12] = period >> 8;
|
||||||
|
sound_ay_registers[13] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_ENV_SHAPE);
|
||||||
|
sound_ay_registers[14] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_PORTA);
|
||||||
|
sound_ay_registers[15] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_PORTB);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
|
||||||
|
ay_change_count = 0;
|
||||||
|
if (yamlLoadHelper.GetSubMap(SS_YAML_KEY_CHANGE))
|
||||||
|
{
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
char szIndex[7];
|
||||||
|
sprintf_s(szIndex, sizeof(szIndex), "0x%04X", ay_change_count);
|
||||||
|
|
||||||
|
bool bFound;
|
||||||
|
std::string value = yamlLoadHelper.LoadString_NoThrow(szIndex, bFound);
|
||||||
|
if (!bFound)
|
||||||
|
break; // done
|
||||||
|
|
||||||
|
if(4 != sscanf_s(value.c_str(), SS_YAML_VALUE_CHANGE_FORMAT,
|
||||||
|
&ay_change[ay_change_count].tstates,
|
||||||
|
&ay_change[ay_change_count].ofs,
|
||||||
|
&ay_change[ay_change_count].reg,
|
||||||
|
&ay_change[ay_change_count].val))
|
||||||
|
throw std::string("Card: AY8910: Failed to scanf change list");
|
||||||
|
|
||||||
|
ay_change_count++;
|
||||||
|
if (ay_change_count > AY_CHANGE_MAX)
|
||||||
|
throw std::string("Card: AY8910: Too many changes");
|
||||||
|
}
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// AY8910 interface
|
// AY8910 interface
|
||||||
|
@ -996,8 +1190,25 @@ void AY8910_InitClock(int nClock)
|
||||||
|
|
||||||
BYTE* AY8910_GetRegsPtr(UINT uChip)
|
BYTE* AY8910_GetRegsPtr(UINT uChip)
|
||||||
{
|
{
|
||||||
if(uChip >= MAX_8910)
|
if (uChip >= MAX_8910)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return g_AY8910[uChip].GetAYRegsPtr();
|
return g_AY8910[uChip].GetAYRegsPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT AY8910_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, UINT uChip, std::string& suffix)
|
||||||
|
{
|
||||||
|
if (uChip >= MAX_8910)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
g_AY8910[uChip].SaveSnapshot(yamlSaveHelper, suffix);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT AY8910_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string& suffix)
|
||||||
|
{
|
||||||
|
if (uChip >= MAX_8910)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return g_AY8910[uChip].LoadSnapshot(yamlLoadHelper, suffix) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ BYTE* AY8910_GetRegsPtr(UINT uChip);
|
||||||
|
|
||||||
void AY8910UpdateSetCycles();
|
void AY8910UpdateSetCycles();
|
||||||
|
|
||||||
|
UINT AY8910_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, UINT uChip, std::string& suffix);
|
||||||
|
UINT AY8910_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string& suffix);
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// FUSE stuff
|
// FUSE stuff
|
||||||
|
|
||||||
|
@ -43,8 +46,11 @@ public:
|
||||||
void sound_frame( void );
|
void sound_frame( void );
|
||||||
BYTE* GetAYRegsPtr( void ) { return &sound_ay_registers[0]; }
|
BYTE* GetAYRegsPtr( void ) { return &sound_ay_registers[0]; }
|
||||||
static void SetCLK( double CLK ) { m_fCurrentCLK_AY8910 = CLK; }
|
static void SetCLK( double CLK ) { m_fCurrentCLK_AY8910 = CLK; }
|
||||||
|
void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, std::string& suffix);
|
||||||
|
bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, std::string& suffix);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void init( void );
|
||||||
void sound_end( void );
|
void sound_end( void );
|
||||||
void sound_ay_overlay( void );
|
void sound_ay_overlay( void );
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Configuration\PropertySheet.h"
|
#include "Configuration\PropertySheet.h"
|
||||||
#include "Tfe\Tfe.h"
|
#include "Tfe\Tfe.h"
|
||||||
|
|
||||||
|
static UINT16 g_AppleWinVersion[4] = {0};
|
||||||
char VERSIONSTRING[16] = "xx.yy.zz.ww";
|
char VERSIONSTRING[16] = "xx.yy.zz.ww";
|
||||||
|
|
||||||
TCHAR *g_pAppTitle = TITLE_APPLE_2E_ENHANCED;
|
TCHAR *g_pAppTitle = TITLE_APPLE_2E_ENHANCED;
|
||||||
|
@ -65,9 +66,6 @@ eApple2Type g_Apple2Type = A2TYPE_APPLE2EENHANCED;
|
||||||
|
|
||||||
bool g_bFullSpeed = false;
|
bool g_bFullSpeed = false;
|
||||||
|
|
||||||
//Pravets 8A/C variables
|
|
||||||
bool P8CAPS_ON = false;
|
|
||||||
bool P8Shift = false;
|
|
||||||
//=================================================
|
//=================================================
|
||||||
|
|
||||||
// Win32
|
// Win32
|
||||||
|
@ -102,8 +100,6 @@ CMouseInterface sg_Mouse;
|
||||||
SS_CARDTYPE g_Slot4 = CT_Empty;
|
SS_CARDTYPE g_Slot4 = CT_Empty;
|
||||||
SS_CARDTYPE g_Slot5 = CT_Empty;
|
SS_CARDTYPE g_Slot5 = CT_Empty;
|
||||||
|
|
||||||
eCPU g_ActiveCPU = CPU_6502;
|
|
||||||
|
|
||||||
HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE; // Cmd-line specified custom ROM at $F800..$FFFF
|
HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE; // Cmd-line specified custom ROM at $F800..$FFFF
|
||||||
static bool g_bCustomRomF8Failed = false; // Set if custom ROM file failed
|
static bool g_bCustomRomF8Failed = false; // Set if custom ROM file failed
|
||||||
|
|
||||||
|
@ -114,6 +110,22 @@ CSpeech g_Speech;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
eApple2Type GetApple2Type(void)
|
||||||
|
{
|
||||||
|
return g_Apple2Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetApple2Type(eApple2Type type)
|
||||||
|
{
|
||||||
|
g_Apple2Type = type;
|
||||||
|
SetMainCpuDefault(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
const UINT16* GetAppleWinVersion(void)
|
||||||
|
{
|
||||||
|
return &g_AppleWinVersion[0];
|
||||||
|
}
|
||||||
|
|
||||||
bool GetLoadedSaveStateFlag(void)
|
bool GetLoadedSaveStateFlag(void)
|
||||||
{
|
{
|
||||||
return g_bLoadedSaveState;
|
return g_bLoadedSaveState;
|
||||||
|
@ -371,35 +383,13 @@ static void LoadConfigOldJoystick(const UINT uJoyNum)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
joytype[uJoyNum] = uNewJoyType;
|
JoySetJoyType(uJoyNum, uNewJoyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reads configuration from the registry entries
|
//Sets the character set for the Apple model/clone
|
||||||
void LoadConfiguration(void)
|
void SetCharsetType(void)
|
||||||
{
|
{
|
||||||
DWORD dwComputerType;
|
switch ( GetApple2Type() )
|
||||||
|
|
||||||
if (REGLOAD(TEXT(REGVALUE_APPLE2_TYPE), &dwComputerType))
|
|
||||||
{
|
|
||||||
if ((dwComputerType >= A2TYPE_MAX) || (dwComputerType >= A2TYPE_UNDEFINED && dwComputerType < A2TYPE_CLONE))
|
|
||||||
dwComputerType = A2TYPE_APPLE2EENHANCED;
|
|
||||||
|
|
||||||
g_Apple2Type = (eApple2Type) dwComputerType;
|
|
||||||
}
|
|
||||||
else // Support older AppleWin registry entries
|
|
||||||
{
|
|
||||||
REGLOAD(TEXT(REGVALUE_OLD_APPLE2_TYPE), &dwComputerType);
|
|
||||||
switch (dwComputerType)
|
|
||||||
{
|
|
||||||
// NB. No A2TYPE_APPLE2E (this is correct)
|
|
||||||
case 0: g_Apple2Type = A2TYPE_APPLE2;
|
|
||||||
case 1: g_Apple2Type = A2TYPE_APPLE2PLUS;
|
|
||||||
case 2: g_Apple2Type = A2TYPE_APPLE2EENHANCED;
|
|
||||||
default: g_Apple2Type = A2TYPE_APPLE2EENHANCED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (g_Apple2Type) //Sets the character set for the Apple model/clone
|
|
||||||
{
|
{
|
||||||
case A2TYPE_APPLE2: g_nCharsetType = 0; break;
|
case A2TYPE_APPLE2: g_nCharsetType = 0; break;
|
||||||
case A2TYPE_APPLE2PLUS: g_nCharsetType = 0; break;
|
case A2TYPE_APPLE2PLUS: g_nCharsetType = 0; break;
|
||||||
|
@ -408,11 +398,67 @@ void LoadConfiguration(void)
|
||||||
case A2TYPE_PRAVETS82: g_nCharsetType = 1; break;
|
case A2TYPE_PRAVETS82: g_nCharsetType = 1; break;
|
||||||
case A2TYPE_PRAVETS8A: g_nCharsetType = 2; break;
|
case A2TYPE_PRAVETS8A: g_nCharsetType = 2; break;
|
||||||
case A2TYPE_PRAVETS8M: g_nCharsetType = 3; break; //This charset has a very small difference with the PRAVETS82 one an probably has some misplaced characters. Still the Pravets82 charset is used, because setting charset to 3 results in some problems.
|
case A2TYPE_PRAVETS8M: g_nCharsetType = 3; break; //This charset has a very small difference with the PRAVETS82 one an probably has some misplaced characters. Still the Pravets82 charset is used, because setting charset to 3 results in some problems.
|
||||||
|
default:
|
||||||
|
_ASSERT(0);
|
||||||
|
g_nCharsetType = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Reads configuration from the registry entries
|
||||||
|
void LoadConfiguration(void)
|
||||||
|
{
|
||||||
|
DWORD dwComputerType;
|
||||||
|
eApple2Type apple2Type = A2TYPE_APPLE2EENHANCED;
|
||||||
|
|
||||||
|
if (REGLOAD(TEXT(REGVALUE_APPLE2_TYPE), &dwComputerType))
|
||||||
|
{
|
||||||
|
if ((dwComputerType >= A2TYPE_MAX) || (dwComputerType >= A2TYPE_UNDEFINED && dwComputerType < A2TYPE_CLONE))
|
||||||
|
dwComputerType = A2TYPE_APPLE2EENHANCED;
|
||||||
|
|
||||||
|
apple2Type = (eApple2Type) dwComputerType;
|
||||||
|
}
|
||||||
|
else // Support older AppleWin registry entries
|
||||||
|
{
|
||||||
|
REGLOAD(TEXT(REGVALUE_OLD_APPLE2_TYPE), &dwComputerType);
|
||||||
|
switch (dwComputerType)
|
||||||
|
{
|
||||||
|
// NB. No A2TYPE_APPLE2E (this is correct)
|
||||||
|
case 0: apple2Type = A2TYPE_APPLE2; break;
|
||||||
|
case 1: apple2Type = A2TYPE_APPLE2PLUS; break;
|
||||||
|
case 2: apple2Type = A2TYPE_APPLE2EENHANCED; break;
|
||||||
|
default: apple2Type = A2TYPE_APPLE2EENHANCED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!REGLOAD(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), &joytype[JN_JOYSTICK0]))
|
SetApple2Type(apple2Type);
|
||||||
|
SetCharsetType();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
DWORD dwCpuType;
|
||||||
|
eCpuType cpu = CPU_65C02;
|
||||||
|
|
||||||
|
if (REGLOAD(TEXT(REGVALUE_CPU_TYPE), &dwCpuType))
|
||||||
|
{
|
||||||
|
if (dwCpuType != CPU_6502 && dwCpuType != CPU_65C02)
|
||||||
|
dwCpuType = CPU_65C02;
|
||||||
|
|
||||||
|
cpu = (eCpuType) dwCpuType;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetMainCpu(cpu);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
DWORD dwJoyType;
|
||||||
|
if (REGLOAD(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), &dwJoyType))
|
||||||
|
JoySetJoyType(JN_JOYSTICK0, dwJoyType);
|
||||||
|
else
|
||||||
LoadConfigOldJoystick(JN_JOYSTICK0);
|
LoadConfigOldJoystick(JN_JOYSTICK0);
|
||||||
if (!REGLOAD(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), &joytype[JN_JOYSTICK1]))
|
|
||||||
|
if (REGLOAD(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), &dwJoyType))
|
||||||
|
JoySetJoyType(JN_JOYSTICK1, dwJoyType);
|
||||||
|
else
|
||||||
LoadConfigOldJoystick(JN_JOYSTICK1);
|
LoadConfigOldJoystick(JN_JOYSTICK1);
|
||||||
|
|
||||||
REGLOAD(TEXT("Sound Emulation") ,&soundtype);
|
REGLOAD(TEXT("Sound Emulation") ,&soundtype);
|
||||||
|
@ -469,12 +515,6 @@ void LoadConfiguration(void)
|
||||||
if(REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp))
|
if(REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp))
|
||||||
HD_SetEnabled(dwTmp ? true : false);
|
HD_SetEnabled(dwTmp ? true : false);
|
||||||
|
|
||||||
char szHDVPathname[MAX_PATH] = {0};
|
|
||||||
if(RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_LAST_HARDDISK_1), 1, szHDVPathname, sizeof(szHDVPathname)))
|
|
||||||
HD_InsertDisk(HARDDISK_1, szHDVPathname);
|
|
||||||
if(RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_LAST_HARDDISK_2), 1, szHDVPathname, sizeof(szHDVPathname)))
|
|
||||||
HD_InsertDisk(HARDDISK_2, szHDVPathname);
|
|
||||||
|
|
||||||
if(REGLOAD(TEXT(REGVALUE_PDL_XTRIM), &dwTmp))
|
if(REGLOAD(TEXT(REGVALUE_PDL_XTRIM), &dwTmp))
|
||||||
JoySetTrim((short)dwTmp, true);
|
JoySetTrim((short)dwTmp, true);
|
||||||
if(REGLOAD(TEXT(REGVALUE_PDL_YTRIM), &dwTmp))
|
if(REGLOAD(TEXT(REGVALUE_PDL_YTRIM), &dwTmp))
|
||||||
|
@ -500,15 +540,20 @@ void LoadConfiguration(void)
|
||||||
if(REGLOAD(TEXT(REGVALUE_SLOT5), &dwTmp))
|
if(REGLOAD(TEXT(REGVALUE_SLOT5), &dwTmp))
|
||||||
g_Slot5 = (SS_CARDTYPE) dwTmp;
|
g_Slot5 = (SS_CARDTYPE) dwTmp;
|
||||||
|
|
||||||
if (g_Slot4 == CT_MockingboardC || g_Slot4 == CT_Phasor)
|
|
||||||
MB_SetSoundcardType(g_Slot4);
|
|
||||||
else
|
|
||||||
MB_SetSoundcardType(CT_Empty);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
char szFilename[MAX_PATH] = {0};
|
char szFilename[MAX_PATH] = {0};
|
||||||
|
|
||||||
|
RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, szFilename, MAX_PATH);
|
||||||
|
if (szFilename[0] == 0)
|
||||||
|
GetCurrentDirectory(sizeof(szFilename), szFilename);
|
||||||
|
SetCurrentImageDir(szFilename);
|
||||||
|
|
||||||
|
HD_LoadLastDiskImage(HARDDISK_1);
|
||||||
|
HD_LoadLastDiskImage(HARDDISK_2);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
// Current/Starting Dir is the "root" of where the user keeps his disk images
|
// Current/Starting Dir is the "root" of where the user keeps his disk images
|
||||||
RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, szFilename, MAX_PATH);
|
RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, szFilename, MAX_PATH);
|
||||||
if (szFilename[0] == 0)
|
if (szFilename[0] == 0)
|
||||||
|
@ -550,7 +595,7 @@ bool SetCurrentImageDir(const char* pszImageDir)
|
||||||
strcpy(g_sCurrentDir, pszImageDir);
|
strcpy(g_sCurrentDir, pszImageDir);
|
||||||
|
|
||||||
int nLen = strlen( g_sCurrentDir );
|
int nLen = strlen( g_sCurrentDir );
|
||||||
if( g_sCurrentDir[ nLen - 1 ] != '\\' )
|
if ((nLen > 0) && (g_sCurrentDir[ nLen - 1 ] != '\\'))
|
||||||
{
|
{
|
||||||
g_sCurrentDir[ nLen + 0 ] = '\\';
|
g_sCurrentDir[ nLen + 0 ] = '\\';
|
||||||
g_sCurrentDir[ nLen + 1 ] = 0;
|
g_sCurrentDir[ nLen + 1 ] = 0;
|
||||||
|
@ -739,10 +784,12 @@ static int DoDiskInsert(const int nDrive, LPCSTR szFileName)
|
||||||
|
|
||||||
int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||||
{
|
{
|
||||||
|
bool bShutdown = false;
|
||||||
bool bSetFullScreen = false;
|
bool bSetFullScreen = false;
|
||||||
bool bBoot = false;
|
bool bBoot = false;
|
||||||
LPSTR szImageName_drive1 = NULL;
|
LPSTR szImageName_drive1 = NULL;
|
||||||
LPSTR szImageName_drive2 = NULL;
|
LPSTR szImageName_drive2 = NULL;
|
||||||
|
LPSTR szSnapshotName = NULL;
|
||||||
const std::string strCmdLine(lpCmdLine); // Keep a copy for log ouput
|
const std::string strCmdLine(lpCmdLine); // Keep a copy for log ouput
|
||||||
|
|
||||||
while (*lpCmdLine)
|
while (*lpCmdLine)
|
||||||
|
@ -774,6 +821,12 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||||
lpNextArg = GetNextArg(lpNextArg);
|
lpNextArg = GetNextArg(lpNextArg);
|
||||||
szImageName_drive2 = lpCmdLine;
|
szImageName_drive2 = lpCmdLine;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(lpCmdLine, "-load-state") == 0)
|
||||||
|
{
|
||||||
|
lpCmdLine = GetCurrArg(lpNextArg);
|
||||||
|
lpNextArg = GetNextArg(lpNextArg);
|
||||||
|
szSnapshotName = lpCmdLine;
|
||||||
|
}
|
||||||
else if (strcmp(lpCmdLine, "-f") == 0)
|
else if (strcmp(lpCmdLine, "-f") == 0)
|
||||||
{
|
{
|
||||||
bSetFullScreen = true;
|
bSetFullScreen = true;
|
||||||
|
@ -811,8 +864,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||||
lpCmdLine = GetCurrArg(lpNextArg);
|
lpCmdLine = GetCurrArg(lpNextArg);
|
||||||
lpNextArg = GetNextArg(lpNextArg);
|
lpNextArg = GetNextArg(lpNextArg);
|
||||||
g_uMaxExPages = atoi(lpCmdLine);
|
g_uMaxExPages = atoi(lpCmdLine);
|
||||||
if (g_uMaxExPages > 127)
|
if (g_uMaxExPages > kMaxExMemoryBanks)
|
||||||
g_uMaxExPages = 128;
|
g_uMaxExPages = kMaxExMemoryBanks;
|
||||||
else if (g_uMaxExPages < 1)
|
else if (g_uMaxExPages < 1)
|
||||||
g_uMaxExPages = 1;
|
g_uMaxExPages = 1;
|
||||||
}
|
}
|
||||||
|
@ -905,10 +958,10 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||||
|
|
||||||
// Construct version string from fixed file info block
|
// Construct version string from fixed file info block
|
||||||
|
|
||||||
unsigned long major = pFixedFileInfo->dwFileVersionMS >> 16;
|
unsigned long major = g_AppleWinVersion[0] = pFixedFileInfo->dwFileVersionMS >> 16;
|
||||||
unsigned long minor = pFixedFileInfo->dwFileVersionMS & 0xffff;
|
unsigned long minor = g_AppleWinVersion[1] = pFixedFileInfo->dwFileVersionMS & 0xffff;
|
||||||
unsigned long fix = pFixedFileInfo->dwFileVersionLS >> 16;
|
unsigned long fix = g_AppleWinVersion[2] = pFixedFileInfo->dwFileVersionLS >> 16;
|
||||||
unsigned long fix_minor = pFixedFileInfo->dwFileVersionLS & 0xffff;
|
unsigned long fix_minor = g_AppleWinVersion[3] = pFixedFileInfo->dwFileVersionLS & 0xffff;
|
||||||
sprintf(VERSIONSTRING, "%d.%d.%d.%d", major, minor, fix, fix_minor); // potential buffer overflow
|
sprintf(VERSIONSTRING, "%d.%d.%d.%d", major, minor, fix, fix_minor); // potential buffer overflow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1003,7 +1056,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||||
if (bShowAboutDlg)
|
if (bShowAboutDlg)
|
||||||
{
|
{
|
||||||
if (!AboutDlg())
|
if (!AboutDlg())
|
||||||
PostMessage(g_hFrameWindow, WM_DESTROY, 0, 0); // Close everything down
|
bShutdown = true; // Close everything down
|
||||||
else
|
else
|
||||||
RegSaveString(TEXT(REG_CONFIG), TEXT(REGVALUE_VERSION), 1, VERSIONSTRING); // Only save version after user accepts license
|
RegSaveString(TEXT(REG_CONFIG), TEXT(REGVALUE_VERSION), 1, VERSIONSTRING); // Only save version after user accepts license
|
||||||
}
|
}
|
||||||
|
@ -1019,21 +1072,46 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||||
if (!bSysClkOK)
|
if (!bSysClkOK)
|
||||||
{
|
{
|
||||||
MessageBox(g_hFrameWindow, "DirectX failed to create SystemClock instance", TEXT("AppleWin Error"), MB_OK);
|
MessageBox(g_hFrameWindow, "DirectX failed to create SystemClock instance", TEXT("AppleWin Error"), MB_OK);
|
||||||
PostMessage(g_hFrameWindow, WM_DESTROY, 0, 0); // Close everything down
|
bShutdown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_bCustomRomF8Failed)
|
if (g_bCustomRomF8Failed)
|
||||||
{
|
{
|
||||||
MessageBox(g_hFrameWindow, "Failed to load custom F8 rom (not found or not exactly 2KB)", TEXT("AppleWin Error"), MB_OK);
|
MessageBox(g_hFrameWindow, "Failed to load custom F8 rom (not found or not exactly 2KB)", TEXT("AppleWin Error"), MB_OK);
|
||||||
PostMessage(g_hFrameWindow, WM_DESTROY, 0, 0); // Close everything down
|
bShutdown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
tfe_init();
|
tfe_init();
|
||||||
LogFileOutput("Main: tfe_init()\n");
|
LogFileOutput("Main: tfe_init()\n");
|
||||||
|
|
||||||
|
if (szSnapshotName)
|
||||||
|
{
|
||||||
|
// Override value just loaded from Registry by LoadConfiguration()
|
||||||
|
// . NB. Registry value is not updated with this cmd-line value
|
||||||
|
Snapshot_SetFilename(szSnapshotName);
|
||||||
|
Snapshot_LoadState();
|
||||||
|
bBoot = true;
|
||||||
|
#if _DEBUG && 0 // Debug/test: Save a duplicate of the save-state file in tmp folder
|
||||||
|
std::string saveName = std::string("tmp\\") + std::string(szSnapshotName);
|
||||||
|
Snapshot_SetFilename(saveName);
|
||||||
|
g_bSaveStateOnExit = true;
|
||||||
|
bShutdown = true;
|
||||||
|
#endif
|
||||||
|
szSnapshotName = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Snapshot_Startup(); // Do this after everything has been init'ed
|
Snapshot_Startup(); // Do this after everything has been init'ed
|
||||||
LogFileOutput("Main: Snapshot_Startup()\n");
|
LogFileOutput("Main: Snapshot_Startup()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bShutdown)
|
||||||
|
{
|
||||||
|
PostMessage(g_hFrameWindow, WM_DESTROY, 0, 0); // Close everything down
|
||||||
|
// NB. If shutting down, then don't post any other messages (GH#286)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (bSetFullScreen)
|
if (bSetFullScreen)
|
||||||
{
|
{
|
||||||
PostMessage(g_hFrameWindow, WM_USER_FULLSCREEN, 0, 0);
|
PostMessage(g_hFrameWindow, WM_USER_FULLSCREEN, 0, 0);
|
||||||
|
@ -1045,6 +1123,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||||
PostMessage(g_hFrameWindow, WM_USER_BOOT, 0, 0);
|
PostMessage(g_hFrameWindow, WM_USER_BOOT, 0, 0);
|
||||||
bBoot = false;
|
bBoot = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ENTER THE MAIN MESSAGE LOOP
|
// ENTER THE MAIN MESSAGE LOOP
|
||||||
LogFileOutput("Main: EnterMessageLoop()\n");
|
LogFileOutput("Main: EnterMessageLoop()\n");
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Structs.h"
|
#include "SaveState_Structs_common.h"
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
void SetCurrentCLK6502();
|
void SetCurrentCLK6502();
|
||||||
bool SetCurrentImageDir(const char* pszImageDir);
|
bool SetCurrentImageDir(const char* pszImageDir);
|
||||||
|
void SetCharsetType(void);
|
||||||
|
|
||||||
|
extern const UINT16* GetAppleWinVersion(void);
|
||||||
extern char VERSIONSTRING[]; // Constructed in WinMain()
|
extern char VERSIONSTRING[]; // Constructed in WinMain()
|
||||||
|
|
||||||
extern TCHAR *g_pAppTitle;
|
extern TCHAR *g_pAppTitle;
|
||||||
|
|
||||||
extern eApple2Type g_Apple2Type;
|
extern eApple2Type g_Apple2Type;
|
||||||
|
eApple2Type GetApple2Type(void);
|
||||||
|
void SetApple2Type(eApple2Type type);
|
||||||
|
|
||||||
extern bool g_bFullSpeed;
|
extern bool g_bFullSpeed;
|
||||||
|
|
||||||
//Pravets 8A/C only variables
|
|
||||||
extern bool P8CAPS_ON;
|
|
||||||
extern bool P8Shift;
|
|
||||||
//===========================================
|
//===========================================
|
||||||
|
|
||||||
// Win32
|
// Win32
|
||||||
|
@ -49,9 +49,6 @@ extern SS_CARDTYPE g_Slot5; // Mockingboard, Z80, in slot5
|
||||||
|
|
||||||
extern HANDLE g_hCustomRomF8; // NULL if no custom rom
|
extern HANDLE g_hCustomRomF8; // NULL if no custom rom
|
||||||
|
|
||||||
enum eCPU {CPU_6502=1, CPU_Z80};
|
|
||||||
extern eCPU g_ActiveCPU;
|
|
||||||
|
|
||||||
#ifdef USE_SPEECH_API
|
#ifdef USE_SPEECH_API
|
||||||
class CSpeech;
|
class CSpeech;
|
||||||
extern CSpeech g_Speech;
|
extern CSpeech g_Speech;
|
||||||
|
|
147
source/CPU.cpp
147
source/CPU.cpp
|
@ -63,7 +63,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
//
|
//
|
||||||
// What about these:
|
// What about these:
|
||||||
// . 65C02: STZ?, TRB?, TSB?
|
// . 65C02: STZ?, TRB?, TSB?
|
||||||
// . Answer: TRB & TSB don't have affected adressing modes
|
// . Answer: TRB & TSB don't have affected addressing modes
|
||||||
// . STZ probably doesn't add a cycle since otherwise it would be slower than STA which doesn't make sense.
|
// . STZ probably doesn't add a cycle since otherwise it would be slower than STA which doesn't make sense.
|
||||||
//
|
//
|
||||||
// NB. 'Zero-page indexed' opcodes wrap back to zero-page.
|
// NB. 'Zero-page indexed' opcodes wrap back to zero-page.
|
||||||
|
@ -103,6 +103,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Z80VICE\z80mem.h"
|
#include "Z80VICE\z80mem.h"
|
||||||
|
|
||||||
#include "Debugger\Debug.h"
|
#include "Debugger\Debug.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
// 6502 Accumulator Bit Flags
|
// 6502 Accumulator Bit Flags
|
||||||
#define AF_SIGN 0x80
|
#define AF_SIGN 0x80
|
||||||
|
@ -148,6 +149,53 @@ static volatile UINT32 g_bmIRQ = 0;
|
||||||
static volatile UINT32 g_bmNMI = 0;
|
static volatile UINT32 g_bmNMI = 0;
|
||||||
static volatile BOOL g_bNmiFlank = FALSE; // Positive going flank on NMI line
|
static volatile BOOL g_bNmiFlank = FALSE; // Positive going flank on NMI line
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
static eCpuType g_MainCPU = CPU_65C02;
|
||||||
|
static eCpuType g_ActiveCPU = CPU_65C02;
|
||||||
|
|
||||||
|
eCpuType GetMainCpu(void)
|
||||||
|
{
|
||||||
|
return g_MainCPU;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMainCpu(eCpuType cpu)
|
||||||
|
{
|
||||||
|
_ASSERT(cpu != CPU_Z80);
|
||||||
|
if (cpu == CPU_Z80)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_MainCPU = cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsCpu65C02(eApple2Type apple2Type)
|
||||||
|
{
|
||||||
|
// NB. All Pravets clones are 6502 (GH#307)
|
||||||
|
return (apple2Type == A2TYPE_APPLE2EENHANCED) || (apple2Type & A2TYPE_APPLE2C);
|
||||||
|
}
|
||||||
|
|
||||||
|
eCpuType ProbeMainCpuDefault(eApple2Type apple2Type)
|
||||||
|
{
|
||||||
|
return IsCpu65C02(apple2Type) ? CPU_65C02 : CPU_6502;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMainCpuDefault(eApple2Type apple2Type)
|
||||||
|
{
|
||||||
|
SetMainCpu( ProbeMainCpuDefault(apple2Type) );
|
||||||
|
}
|
||||||
|
|
||||||
|
eCpuType GetActiveCpu(void)
|
||||||
|
{
|
||||||
|
return g_ActiveCPU;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetActiveCpu(eCpuType cpu)
|
||||||
|
{
|
||||||
|
g_ActiveCPU = cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
#include "cpu/cpu_general.inl"
|
#include "cpu/cpu_general.inl"
|
||||||
|
|
||||||
#include "cpu/cpu_instructions.inl"
|
#include "cpu/cpu_instructions.inl"
|
||||||
|
@ -409,8 +457,8 @@ static __forceinline void CheckInterruptSources(ULONG uExecutedCycles)
|
||||||
|
|
||||||
static DWORD InternalCpuExecute (DWORD uTotalCycles)
|
static DWORD InternalCpuExecute (DWORD uTotalCycles)
|
||||||
{
|
{
|
||||||
if (IS_APPLE2 || (g_Apple2Type == A2TYPE_APPLE2E))
|
if (GetMainCpu() == CPU_6502)
|
||||||
return Cpu6502(uTotalCycles); // Apple ][, ][+, //e
|
return Cpu6502(uTotalCycles); // Apple ][, ][+, //e, Clones
|
||||||
else
|
else
|
||||||
return Cpu65C02(uTotalCycles); // Enhanced Apple //e
|
return Cpu65C02(uTotalCycles); // Enhanced Apple //e
|
||||||
}
|
}
|
||||||
|
@ -639,36 +687,83 @@ void CpuReset()
|
||||||
|
|
||||||
regs.bJammed = 0;
|
regs.bJammed = 0;
|
||||||
|
|
||||||
g_ActiveCPU = CPU_6502;
|
SetActiveCpu( GetMainCpu() );
|
||||||
z80_reset();
|
z80_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD CpuGetSnapshot(SS_CPU6502* pSS)
|
void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, const BYTE SP, const USHORT PC, const unsigned __int64 CumulativeCycles)
|
||||||
{
|
{
|
||||||
pSS->A = regs.a;
|
regs.a = A;
|
||||||
pSS->X = regs.x;
|
regs.x = X;
|
||||||
pSS->Y = regs.y;
|
regs.y = Y;
|
||||||
pSS->P = regs.ps | AF_RESERVED | AF_BREAK;
|
regs.ps = P | (AF_RESERVED | AF_BREAK);
|
||||||
pSS->S = (BYTE) (regs.sp & 0xff);
|
regs.sp = ((USHORT)SP) | 0x100;
|
||||||
pSS->PC = regs.pc;
|
regs.pc = PC;
|
||||||
pSS->g_nCumulativeCycles = g_nCumulativeCycles;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD CpuSetSnapshot(SS_CPU6502* pSS)
|
|
||||||
{
|
|
||||||
regs.a = pSS->A;
|
|
||||||
regs.x = pSS->X;
|
|
||||||
regs.y = pSS->Y;
|
|
||||||
regs.ps = pSS->P | AF_RESERVED | AF_BREAK;
|
|
||||||
regs.sp = (USHORT)pSS->S | 0x100;
|
|
||||||
regs.pc = pSS->PC;
|
|
||||||
CpuIrqReset();
|
CpuIrqReset();
|
||||||
CpuNmiReset();
|
CpuNmiReset();
|
||||||
g_nCumulativeCycles = pSS->g_nCumulativeCycles;
|
g_nCumulativeCycles = CumulativeCycles;
|
||||||
|
}
|
||||||
return 0;
|
|
||||||
|
//
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_CPU_TYPE "Type"
|
||||||
|
#define SS_YAML_KEY_REGA "A"
|
||||||
|
#define SS_YAML_KEY_REGX "X"
|
||||||
|
#define SS_YAML_KEY_REGY "Y"
|
||||||
|
#define SS_YAML_KEY_REGP "P"
|
||||||
|
#define SS_YAML_KEY_REGS "S"
|
||||||
|
#define SS_YAML_KEY_REGPC "PC"
|
||||||
|
#define SS_YAML_KEY_CUMULATIVECYCLES "Cumulative Cycles"
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_6502 "6502"
|
||||||
|
#define SS_YAML_VALUE_65C02 "65C02"
|
||||||
|
|
||||||
|
static std::string CpuGetSnapshotStructName(void)
|
||||||
|
{
|
||||||
|
static const std::string name("CPU");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpuSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
regs.ps |= (AF_RESERVED | AF_BREAK);
|
||||||
|
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", CpuGetSnapshotStructName().c_str());
|
||||||
|
yamlSaveHelper.SaveString(SS_YAML_KEY_CPU_TYPE, GetMainCpu() == CPU_6502 ? SS_YAML_VALUE_6502 : SS_YAML_VALUE_65C02);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGA, regs.a);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGX, regs.x);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGY, regs.y);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGP, regs.ps);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGS, (BYTE) regs.sp);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGPC, regs.pc);
|
||||||
|
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_CUMULATIVECYCLES, g_nCumulativeCycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(CpuGetSnapshotStructName()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string cpuType = yamlLoadHelper.LoadString(SS_YAML_KEY_CPU_TYPE);
|
||||||
|
eCpuType cpu;
|
||||||
|
if (cpuType == SS_YAML_VALUE_6502) cpu = CPU_6502;
|
||||||
|
else if (cpuType == SS_YAML_VALUE_65C02) cpu = CPU_65C02;
|
||||||
|
else throw std::string("Load: Unknown main CPU type");
|
||||||
|
SetMainCpu(cpu);
|
||||||
|
|
||||||
|
regs.a = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGA);
|
||||||
|
regs.x = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGX);
|
||||||
|
regs.y = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGY);
|
||||||
|
regs.ps = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGP) | (AF_RESERVED | AF_BREAK);
|
||||||
|
regs.sp = (USHORT) ((yamlLoadHelper.LoadUint(SS_YAML_KEY_REGS) & 0xff) | 0x100);
|
||||||
|
regs.pc = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGPC);
|
||||||
|
|
||||||
|
CpuIrqReset();
|
||||||
|
CpuNmiReset();
|
||||||
|
g_nCumulativeCycles = yamlLoadHelper.LoadUint64(SS_YAML_KEY_CUMULATIVECYCLES);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
}
|
}
|
||||||
|
|
19
source/CPU.h
19
source/CPU.h
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef struct _regsrec {
|
struct regsrec
|
||||||
|
{
|
||||||
BYTE a; // accumulator
|
BYTE a; // accumulator
|
||||||
BYTE x; // index X
|
BYTE x; // index X
|
||||||
BYTE y; // index Y
|
BYTE y; // index Y
|
||||||
|
@ -8,7 +9,7 @@ typedef struct _regsrec {
|
||||||
WORD pc; // program counter
|
WORD pc; // program counter
|
||||||
WORD sp; // stack pointer
|
WORD sp; // stack pointer
|
||||||
BYTE bJammed; // CPU has crashed (NMOS 6502 only)
|
BYTE bJammed; // CPU has crashed (NMOS 6502 only)
|
||||||
} regsrec, *regsptr;
|
};
|
||||||
|
|
||||||
extern regsrec regs;
|
extern regsrec regs;
|
||||||
extern unsigned __int64 g_nCumulativeCycles;
|
extern unsigned __int64 g_nCumulativeCycles;
|
||||||
|
@ -26,10 +27,20 @@ void CpuNmiReset();
|
||||||
void CpuNmiAssert(eIRQSRC Device);
|
void CpuNmiAssert(eIRQSRC Device);
|
||||||
void CpuNmiDeassert(eIRQSRC Device);
|
void CpuNmiDeassert(eIRQSRC Device);
|
||||||
void CpuReset ();
|
void CpuReset ();
|
||||||
DWORD CpuGetSnapshot(SS_CPU6502* pSS);
|
void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, const BYTE SP, const USHORT PC, const unsigned __int64 CumulativeCycles);
|
||||||
DWORD CpuSetSnapshot(SS_CPU6502* pSS);
|
void CpuSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
void CpuLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
|
||||||
|
|
||||||
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles);
|
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles);
|
||||||
void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles);
|
void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles);
|
||||||
|
|
||||||
DWORD CpuGetEmulationTime_ms(void);
|
DWORD CpuGetEmulationTime_ms(void);
|
||||||
|
|
||||||
|
enum eCpuType {CPU_6502=1, CPU_65C02, CPU_Z80}; // Don't change! Persisted to Registry
|
||||||
|
|
||||||
|
eCpuType GetMainCpu(void);
|
||||||
|
void SetMainCpu(eCpuType cpu);
|
||||||
|
eCpuType ProbeMainCpuDefault(eApple2Type apple2Type);
|
||||||
|
void SetMainCpuDefault(eApple2Type apple2Type);
|
||||||
|
eCpuType GetActiveCpu(void);
|
||||||
|
void SetActiveCpu(eCpuType cpu);
|
||||||
|
|
|
@ -35,7 +35,6 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
|
||||||
WORD val;
|
WORD val;
|
||||||
AF_TO_EF
|
AF_TO_EF
|
||||||
ULONG uExecutedCycles = 0;
|
ULONG uExecutedCycles = 0;
|
||||||
BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA)
|
|
||||||
WORD base;
|
WORD base;
|
||||||
g_bDebugBreakpointHit = 0;
|
g_bDebugBreakpointHit = 0;
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
|
||||||
ULONG uPreviousCycles = uExecutedCycles;
|
ULONG uPreviousCycles = uExecutedCycles;
|
||||||
// NTSC_END
|
// NTSC_END
|
||||||
|
|
||||||
if (g_ActiveCPU == CPU_Z80)
|
if (GetActiveCpu() == CPU_Z80)
|
||||||
{
|
{
|
||||||
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
|
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
|
||||||
}
|
}
|
||||||
|
@ -68,31 +67,31 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
|
||||||
case 0x04: $ ZPG NOP CYC(3) break;
|
case 0x04: $ ZPG NOP CYC(3) break;
|
||||||
case 0x05: ZPG ORA CYC(3) break;
|
case 0x05: ZPG ORA CYC(3) break;
|
||||||
case 0x06: ZPG ASLn CYC(5) break;
|
case 0x06: ZPG ASLn CYC(5) break;
|
||||||
case 0x07: $ ZPG ASO CYC(5) break; // invalid
|
case 0x07: $ ZPG ASO CYC(5) break;
|
||||||
case 0x08: PHP CYC(3) break;
|
case 0x08: PHP CYC(3) break;
|
||||||
case 0x09: IMM ORA CYC(2) break;
|
case 0x09: IMM ORA CYC(2) break;
|
||||||
case 0x0A: asl CYC(2) break;
|
case 0x0A: asl CYC(2) break;
|
||||||
case 0x0B: $ IMM ANC CYC(2) break; // invald
|
case 0x0B: $ IMM ANC CYC(2) break;
|
||||||
case 0x0C: $ abx NOP CYC(4) break;
|
case 0x0C: $ ABSX_OPT NOP CYC(4) break;
|
||||||
case 0x0D: ABS ORA CYC(4) break;
|
case 0x0D: ABS ORA CYC(4) break;
|
||||||
case 0x0E: ABS ASLn CYC(6) break;
|
case 0x0E: ABS ASLn CYC(6) break;
|
||||||
case 0x0F: $ ABS ASO CYC(6) break; // invalid
|
case 0x0F: $ ABS ASO CYC(6) break;
|
||||||
case 0x10: REL BPL CYC(2) break;
|
case 0x10: REL BPL CYC(2) break;
|
||||||
case 0x11: idy ORA CYC(5) break;
|
case 0x11: INDY_OPT ORA CYC(5) break;
|
||||||
case 0x12: $ HLT CYC(2) break;
|
case 0x12: $ HLT CYC(2) break;
|
||||||
case 0x13: $ idy ASO CYC(8) break; // invalid
|
case 0x13: $ INDY_CONST ASO CYC(8) break;
|
||||||
case 0x14: $ zpx NOP CYC(4) break;
|
case 0x14: $ zpx NOP CYC(4) break;
|
||||||
case 0x15: zpx ORA CYC(4) break;
|
case 0x15: zpx ORA CYC(4) break;
|
||||||
case 0x16: zpx ASLn CYC(6) break;
|
case 0x16: zpx ASLn CYC(6) break;
|
||||||
case 0x17: $ zpx ASO CYC(6) break; // invalid
|
case 0x17: $ zpx ASO CYC(6) break;
|
||||||
case 0x18: CLC CYC(2) break;
|
case 0x18: CLC CYC(2) break;
|
||||||
case 0x19: aby ORA CYC(4) break;
|
case 0x19: ABSY_OPT ORA CYC(4) break;
|
||||||
case 0x1A: $ NOP CYC(2) break;
|
case 0x1A: $ NOP CYC(2) break;
|
||||||
case 0x1B: $ aby ASO CYC(7) break; // invalid
|
case 0x1B: $ ABSY_CONST ASO CYC(7) break;
|
||||||
case 0x1C: $ abx NOP CYC(4) break;
|
case 0x1C: $ ABSX_OPT NOP CYC(4) break;
|
||||||
case 0x1D: abx ORA CYC(4) break;
|
case 0x1D: ABSX_OPT ORA CYC(4) break;
|
||||||
case 0x1E: abx ASLn CYC(6) break;
|
case 0x1E: ABSX_CONST ASLn CYC(7) break;
|
||||||
case 0x1F: $ abx ASO CYC(7) break; // invalid
|
case 0x1F: $ ABSX_CONST ASO CYC(7) break;
|
||||||
case 0x20: ABS JSR CYC(6) break;
|
case 0x20: ABS JSR CYC(6) break;
|
||||||
case 0x21: idx AND CYC(6) break;
|
case 0x21: idx AND CYC(6) break;
|
||||||
case 0x22: $ HLT CYC(2) break;
|
case 0x22: $ HLT CYC(2) break;
|
||||||
|
@ -104,63 +103,63 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
|
||||||
case 0x28: PLP CYC(4) break;
|
case 0x28: PLP CYC(4) break;
|
||||||
case 0x29: IMM AND CYC(2) break;
|
case 0x29: IMM AND CYC(2) break;
|
||||||
case 0x2A: rol CYC(2) break;
|
case 0x2A: rol CYC(2) break;
|
||||||
case 0x2B: $ IMM ANC CYC(2) break; // invalid
|
case 0x2B: $ IMM ANC CYC(2) break;
|
||||||
case 0x2C: ABS BIT CYC(4) break;
|
case 0x2C: ABS BIT CYC(4) break;
|
||||||
case 0x2D: ABS AND CYC(2) break;
|
case 0x2D: ABS AND CYC(4) break;
|
||||||
case 0x2E: ABS ROLn CYC(6) break;
|
case 0x2E: ABS ROLn CYC(6) break;
|
||||||
case 0x2F: $ ABS RLA CYC(6) break;
|
case 0x2F: $ ABS RLA CYC(6) break;
|
||||||
case 0x30: REL BMI CYC(2) break;
|
case 0x30: REL BMI CYC(2) break;
|
||||||
case 0x31: idy AND CYC(5) break;
|
case 0x31: INDY_OPT AND CYC(5) break;
|
||||||
case 0x32: $ HLT CYC(2) break;
|
case 0x32: $ HLT CYC(2) break;
|
||||||
case 0x33: $ idy RLA CYC(8) break; // invalid
|
case 0x33: $ INDY_CONST RLA CYC(8) break;
|
||||||
case 0x34: $ zpx NOP CYC(4) break;
|
case 0x34: $ zpx NOP CYC(4) break;
|
||||||
case 0x35: zpx AND CYC(4) break;
|
case 0x35: zpx AND CYC(4) break;
|
||||||
case 0x36: zpx ROLn CYC(6) break;
|
case 0x36: zpx ROLn CYC(6) break;
|
||||||
case 0x37: $ zpx RLA CYC(6) break;
|
case 0x37: $ zpx RLA CYC(6) break;
|
||||||
case 0x38: SEC CYC(2) break;
|
case 0x38: SEC CYC(2) break;
|
||||||
case 0x39: aby AND CYC(4) break;
|
case 0x39: ABSY_OPT AND CYC(4) break;
|
||||||
case 0x3A: $ NOP CYC(2) break;
|
case 0x3A: $ NOP CYC(2) break;
|
||||||
case 0x3B: $ aby RLA CYC(7) break; // invalid
|
case 0x3B: $ ABSY_CONST RLA CYC(7) break;
|
||||||
case 0x3C: $ abx NOP CYC(4) break;
|
case 0x3C: $ ABSX_OPT NOP CYC(4) break;
|
||||||
case 0x3D: abx AND CYC(4) break;
|
case 0x3D: ABSX_OPT AND CYC(4) break;
|
||||||
case 0x3E: abx ROLn CYC(6) break;
|
case 0x3E: ABSX_CONST ROLn CYC(6) break;
|
||||||
case 0x3F: $ abx RLA CYC(7) break; // invalid
|
case 0x3F: $ ABSX_CONST RLA CYC(7) break;
|
||||||
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
|
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
|
||||||
case 0x41: idx EOR CYC(6) break;
|
case 0x41: idx EOR CYC(6) break;
|
||||||
case 0x42: $ HLT CYC(2) break;
|
case 0x42: $ HLT CYC(2) break;
|
||||||
case 0x43: $ idx LSE CYC(8) break; // invalid
|
case 0x43: $ idx LSE CYC(8) break;
|
||||||
case 0x44: $ ZPG NOP CYC(3) break;
|
case 0x44: $ ZPG NOP CYC(3) break;
|
||||||
case 0x45: ZPG EOR CYC(3) break;
|
case 0x45: ZPG EOR CYC(3) break;
|
||||||
case 0x46: ZPG LSRn CYC(5) break;
|
case 0x46: ZPG LSRn CYC(5) break;
|
||||||
case 0x47: $ ZPG LSE CYC(5) break; // invalid
|
case 0x47: $ ZPG LSE CYC(5) break;
|
||||||
case 0x48: PHA CYC(3) break;
|
case 0x48: PHA CYC(3) break;
|
||||||
case 0x49: IMM EOR CYC(2) break;
|
case 0x49: IMM EOR CYC(2) break;
|
||||||
case 0x4A: lsr CYC(2) break;
|
case 0x4A: lsr CYC(2) break;
|
||||||
case 0x4B: $ IMM ALR CYC(2) break; // invalid
|
case 0x4B: $ IMM ALR CYC(2) break;
|
||||||
case 0x4C: ABS JMP CYC(3) break;
|
case 0x4C: ABS JMP CYC(3) break;
|
||||||
case 0x4D: ABS EOR CYC(4) break;
|
case 0x4D: ABS EOR CYC(4) break;
|
||||||
case 0x4E: ABS LSRn CYC(6) break;
|
case 0x4E: ABS LSRn CYC(6) break;
|
||||||
case 0x4F: $ ABS LSE CYC(6) break;
|
case 0x4F: $ ABS LSE CYC(6) break;
|
||||||
case 0x50: REL BVC CYC(2) break;
|
case 0x50: REL BVC CYC(2) break;
|
||||||
case 0x51: idy EOR CYC(5) break;
|
case 0x51: INDY_OPT EOR CYC(5) break;
|
||||||
case 0x52: $ HLT CYC(2) break;
|
case 0x52: $ HLT CYC(2) break;
|
||||||
case 0x53: $ idy LSE CYC(8) break;
|
case 0x53: $ INDY_CONST LSE CYC(8) break;
|
||||||
case 0x54: $ zpx NOP CYC(4) break;
|
case 0x54: $ zpx NOP CYC(4) break;
|
||||||
case 0x55: zpx EOR CYC(4) break;
|
case 0x55: zpx EOR CYC(4) break;
|
||||||
case 0x56: zpx LSRn CYC(6) break;
|
case 0x56: zpx LSRn CYC(6) break;
|
||||||
case 0x57: $ zpx LSE CYC(6) break; // invalid
|
case 0x57: $ zpx LSE CYC(6) break;
|
||||||
case 0x58: CLI CYC(2) break;
|
case 0x58: CLI CYC(2) break;
|
||||||
case 0x59: aby EOR CYC(4) break;
|
case 0x59: ABSY_OPT EOR CYC(4) break;
|
||||||
case 0x5A: $ NOP CYC(2) break;
|
case 0x5A: $ NOP CYC(2) break;
|
||||||
case 0x5B: $ aby LSE CYC(7) break; // invalid
|
case 0x5B: $ ABSY_CONST LSE CYC(7) break;
|
||||||
case 0x5C: $ abx NOP CYC(4) break;
|
case 0x5C: $ ABSX_OPT NOP CYC(4) break;
|
||||||
case 0x5D: abx EOR CYC(4) break;
|
case 0x5D: ABSX_OPT EOR CYC(4) break;
|
||||||
case 0x5E: abx LSRn CYC(6) break;
|
case 0x5E: ABSX_CONST LSRn CYC(6) break;
|
||||||
case 0x5F: $ abx LSE CYC(7) break;
|
case 0x5F: $ ABSX_CONST LSE CYC(7) break;
|
||||||
case 0x60: RTS CYC(6) break;
|
case 0x60: RTS CYC(6) break;
|
||||||
case 0x61: idx ADCn CYC(6) break;
|
case 0x61: idx ADCn CYC(6) break;
|
||||||
case 0x62: $ HLT CYC(2) break;
|
case 0x62: $ HLT CYC(2) break;
|
||||||
case 0x63: $ idx RRA CYC(8) break; // invalid
|
case 0x63: $ idx RRA CYC(8) break;
|
||||||
case 0x64: $ ZPG NOP CYC(3) break;
|
case 0x64: $ ZPG NOP CYC(3) break;
|
||||||
case 0x65: ZPG ADCn CYC(3) break;
|
case 0x65: ZPG ADCn CYC(3) break;
|
||||||
case 0x66: ZPG RORn CYC(5) break;
|
case 0x66: ZPG RORn CYC(5) break;
|
||||||
|
@ -168,156 +167,157 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
|
||||||
case 0x68: PLA CYC(4) break;
|
case 0x68: PLA CYC(4) break;
|
||||||
case 0x69: IMM ADCn CYC(2) break;
|
case 0x69: IMM ADCn CYC(2) break;
|
||||||
case 0x6A: ror CYC(2) break;
|
case 0x6A: ror CYC(2) break;
|
||||||
case 0x6B: $ IMM ARR CYC(2) break; // invalid
|
case 0x6B: $ IMM ARR CYC(2) break;
|
||||||
case 0x6C: IABSNMOS JMP CYC(6) break;
|
case 0x6C: IABS_NMOS JMP CYC(5) break; // GH#264
|
||||||
case 0x6D: ABS ADCn CYC(4) break;
|
case 0x6D: ABS ADCn CYC(4) break;
|
||||||
case 0x6E: ABS RORn CYC(6) break;
|
case 0x6E: ABS RORn CYC(6) break;
|
||||||
case 0x6F: $ ABS RRA CYC(6) break; // invalid
|
case 0x6F: $ ABS RRA CYC(6) break;
|
||||||
case 0x70: REL BVS CYC(2) break;
|
case 0x70: REL BVS CYC(2) break;
|
||||||
case 0x71: idy ADCn CYC(5) break;
|
case 0x71: INDY_OPT ADCn CYC(5) break;
|
||||||
case 0x72: $ HLT CYC(2) break;
|
case 0x72: $ HLT CYC(2) break;
|
||||||
case 0x73: $ idy RRA CYC(8) break; // invalid
|
case 0x73: $ INDY_CONST RRA CYC(8) break;
|
||||||
case 0x74: $ zpx NOP CYC(4) break;
|
case 0x74: $ zpx NOP CYC(4) break;
|
||||||
case 0x75: zpx ADCn CYC(4) break;
|
case 0x75: zpx ADCn CYC(4) break;
|
||||||
case 0x76: zpx RORn CYC(6) break;
|
case 0x76: zpx RORn CYC(6) break;
|
||||||
case 0x77: $ zpx RRA CYC(6) break; // invalid
|
case 0x77: $ zpx RRA CYC(6) break;
|
||||||
case 0x78: SEI CYC(2) break;
|
case 0x78: SEI CYC(2) break;
|
||||||
case 0x79: aby ADCn CYC(4) break;
|
case 0x79: ABSY_OPT ADCn CYC(4) break;
|
||||||
case 0x7A: $ NOP CYC(2) break;
|
case 0x7A: $ NOP CYC(2) break;
|
||||||
case 0x7B: $ aby RRA CYC(7) break; // invalid
|
case 0x7B: $ ABSY_CONST RRA CYC(7) break;
|
||||||
case 0x7C: $ abx NOP CYC(4) break;
|
case 0x7C: $ ABSX_OPT NOP CYC(4) break;
|
||||||
case 0x7D: abx ADCn CYC(4) break;
|
case 0x7D: ABSX_OPT ADCn CYC(4) break;
|
||||||
case 0x7E: abx RORn CYC(6) break;
|
case 0x7E: ABSX_CONST RORn CYC(6) break;
|
||||||
case 0x7F: $ abx RRA CYC(7) break; // invalid
|
case 0x7F: $ ABSX_CONST RRA CYC(7) break;
|
||||||
case 0x80: $ IMM NOP CYC(2) break;
|
case 0x80: $ IMM NOP CYC(2) break;
|
||||||
case 0x81: idx STA CYC(6) break;
|
case 0x81: idx STA CYC(6) break;
|
||||||
case 0x82: $ IMM NOP CYC(2) break;
|
case 0x82: $ IMM NOP CYC(2) break;
|
||||||
case 0x83: $ idx AXS CYC(6) break; // invalid
|
case 0x83: $ idx AXS CYC(6) break;
|
||||||
case 0x84: ZPG STY CYC(3) break;
|
case 0x84: ZPG STY CYC(3) break;
|
||||||
case 0x85: ZPG STA CYC(3) break;
|
case 0x85: ZPG STA CYC(3) break;
|
||||||
case 0x86: ZPG STX CYC(3) break;
|
case 0x86: ZPG STX CYC(3) break;
|
||||||
case 0x87: $ ZPG AXS CYC(3) break; // invalid
|
case 0x87: $ ZPG AXS CYC(3) break;
|
||||||
case 0x88: DEY CYC(2) break;
|
case 0x88: DEY CYC(2) break;
|
||||||
case 0x89: $ IMM NOP CYC(2) break;
|
case 0x89: $ IMM NOP CYC(2) break;
|
||||||
case 0x8A: TXA CYC(2) break;
|
case 0x8A: TXA CYC(2) break;
|
||||||
case 0x8B: $ IMM XAA CYC(2) break; // invalid
|
case 0x8B: $ IMM XAA CYC(2) break;
|
||||||
case 0x8C: ABS STY CYC(4) break;
|
case 0x8C: ABS STY CYC(4) break;
|
||||||
case 0x8D: ABS STA CYC(4) break;
|
case 0x8D: ABS STA CYC(4) break;
|
||||||
case 0x8E: ABS STX CYC(4) break;
|
case 0x8E: ABS STX CYC(4) break;
|
||||||
case 0x8F: $ ABS AXS CYC(4) break; // invalid
|
case 0x8F: $ ABS AXS CYC(4) break;
|
||||||
case 0x90: REL BCC CYC(2) break;
|
case 0x90: REL BCC CYC(2) break;
|
||||||
case 0x91: idy STA CYC(6) break;
|
case 0x91: INDY_CONST STA CYC(6) break;
|
||||||
case 0x92: $ HLT CYC(2) break;
|
case 0x92: $ HLT CYC(2) break;
|
||||||
case 0x93: $ idy AXA CYC(6) break; // invalid
|
case 0x93: $ INDY_CONST AXA CYC(6) break;
|
||||||
case 0x94: zpx STY CYC(4) break;
|
case 0x94: zpx STY CYC(4) break;
|
||||||
case 0x95: zpx STA CYC(4) break;
|
case 0x95: zpx STA CYC(4) break;
|
||||||
case 0x96: zpy STX CYC(4) break;
|
case 0x96: zpy STX CYC(4) break;
|
||||||
case 0x97: $ zpy AXS CYC(4) break; // invalid
|
case 0x97: $ zpy AXS CYC(4) break;
|
||||||
case 0x98: TYA CYC(2) break;
|
case 0x98: TYA CYC(2) break;
|
||||||
case 0x99: aby STA CYC(5) break;
|
case 0x99: ABSY_CONST STA CYC(5) break;
|
||||||
case 0x9A: TXS CYC(2) break;
|
case 0x9A: TXS CYC(2) break;
|
||||||
case 0x9B: $ aby TAS CYC(5) break; // invalid
|
case 0x9B: $ ABSY_CONST TAS CYC(5) break;
|
||||||
case 0x9C: $ abx SAY CYC(5) break; // invalid
|
case 0x9C: $ ABSX_CONST SAY CYC(5) break;
|
||||||
case 0x9D: abx STA CYC(5) break;
|
case 0x9D: ABSX_CONST STA CYC(5) break;
|
||||||
case 0x9E: $ aby XAS CYC(5) break;
|
case 0x9E: $ ABSY_CONST XAS CYC(5) break;
|
||||||
case 0x9F: $ aby AXA CYC(5) break;
|
case 0x9F: $ ABSY_CONST AXA CYC(5) break;
|
||||||
case 0xA0: IMM LDY CYC(2) break;
|
case 0xA0: IMM LDY CYC(2) break;
|
||||||
case 0xA1: idx LDA CYC(6) break;
|
case 0xA1: idx LDA CYC(6) break;
|
||||||
case 0xA2: IMM LDX CYC(2) break;
|
case 0xA2: IMM LDX CYC(2) break;
|
||||||
case 0xA3: $ idx LAX CYC(6) break; // invalid
|
case 0xA3: $ idx LAX CYC(6) break;
|
||||||
case 0xA4: ZPG LDY CYC(3) break;
|
case 0xA4: ZPG LDY CYC(3) break;
|
||||||
case 0xA5: ZPG LDA CYC(3) break;
|
case 0xA5: ZPG LDA CYC(3) break;
|
||||||
case 0xA6: ZPG LDX CYC(3) break;
|
case 0xA6: ZPG LDX CYC(3) break;
|
||||||
case 0xA7: $ ZPG LAX CYC(3) break; // invalid
|
case 0xA7: $ ZPG LAX CYC(3) break;
|
||||||
case 0xA8: TAY CYC(2) break;
|
case 0xA8: TAY CYC(2) break;
|
||||||
case 0xA9: IMM LDA CYC(2) break;
|
case 0xA9: IMM LDA CYC(2) break;
|
||||||
case 0xAA: TAX CYC(2) break;
|
case 0xAA: TAX CYC(2) break;
|
||||||
case 0xAB: $ IMM OAL CYC(2) break; // invalid
|
case 0xAB: $ IMM OAL CYC(2) break;
|
||||||
case 0xAC: ABS LDY CYC(4) break;
|
case 0xAC: ABS LDY CYC(4) break;
|
||||||
case 0xAD: ABS LDA CYC(4) break;
|
case 0xAD: ABS LDA CYC(4) break;
|
||||||
case 0xAE: ABS LDX CYC(4) break;
|
case 0xAE: ABS LDX CYC(4) break;
|
||||||
case 0xAF: $ ABS LAX CYC(4) break; // invalid
|
case 0xAF: $ ABS LAX CYC(4) break;
|
||||||
case 0xB0: REL BCS CYC(2) break;
|
case 0xB0: REL BCS CYC(2) break;
|
||||||
case 0xB1: idy LDA CYC(5) break;
|
case 0xB1: INDY_OPT LDA CYC(5) break;
|
||||||
case 0xB2: $ HLT CYC(2) break;
|
case 0xB2: $ HLT CYC(2) break;
|
||||||
case 0xB3: $ idy LAX CYC(5) break;
|
case 0xB3: $ INDY_OPT LAX CYC(5) break;
|
||||||
case 0xB4: zpx LDY CYC(4) break;
|
case 0xB4: zpx LDY CYC(4) break;
|
||||||
case 0xB5: zpx LDA CYC(4) break;
|
case 0xB5: zpx LDA CYC(4) break;
|
||||||
case 0xB6: zpy LDX CYC(4) break;
|
case 0xB6: zpy LDX CYC(4) break;
|
||||||
case 0xB7: $ zpy LAX CYC(4) break; // invalid
|
case 0xB7: $ zpy LAX CYC(4) break;
|
||||||
case 0xB8: CLV CYC(2) break;
|
case 0xB8: CLV CYC(2) break;
|
||||||
case 0xB9: aby LDA CYC(4) break;
|
case 0xB9: ABSY_OPT LDA CYC(4) break;
|
||||||
case 0xBA: TSX CYC(2) break;
|
case 0xBA: TSX CYC(2) break;
|
||||||
case 0xBB: $ aby LAS CYC(4) break; // invalid
|
case 0xBB: $ ABSY_OPT LAS CYC(4) break;
|
||||||
case 0xBC: abx LDY CYC(4) break;
|
case 0xBC: ABSX_OPT LDY CYC(4) break;
|
||||||
case 0xBD: abx LDA CYC(4) break;
|
case 0xBD: ABSX_OPT LDA CYC(4) break;
|
||||||
case 0xBE: aby LDX CYC(4) break;
|
case 0xBE: ABSY_OPT LDX CYC(4) break;
|
||||||
case 0xBF: $ aby LAX CYC(4) break; // invalid
|
case 0xBF: $ ABSY_OPT LAX CYC(4) break;
|
||||||
case 0xC0: IMM CPY CYC(2) break;
|
case 0xC0: IMM CPY CYC(2) break;
|
||||||
case 0xC1: idx CMP CYC(6) break;
|
case 0xC1: idx CMP CYC(6) break;
|
||||||
case 0xC2: $ IMM NOP CYC(2) break;
|
case 0xC2: $ IMM NOP CYC(2) break;
|
||||||
case 0xC3: $ idx DCM CYC(8) break; // invalid
|
case 0xC3: $ idx DCM CYC(8) break;
|
||||||
case 0xC4: ZPG CPY CYC(3) break;
|
case 0xC4: ZPG CPY CYC(3) break;
|
||||||
case 0xC5: ZPG CMP CYC(3) break;
|
case 0xC5: ZPG CMP CYC(3) break;
|
||||||
case 0xC6: ZPG DECn CYC(5) break;
|
case 0xC6: ZPG DEC CYC(5) break;
|
||||||
case 0xC7: $ ZPG DCM CYC(5) break; // invalid
|
case 0xC7: $ ZPG DCM CYC(5) break;
|
||||||
case 0xC8: INY CYC(2) break;
|
case 0xC8: INY CYC(2) break;
|
||||||
case 0xC9: IMM CMP CYC(2) break;
|
case 0xC9: IMM CMP CYC(2) break;
|
||||||
case 0xCA: DEX CYC(2) break;
|
case 0xCA: DEX CYC(2) break;
|
||||||
case 0xCB: $ IMM SAX CYC(2) break; // invalid
|
case 0xCB: $ IMM SAX CYC(2) break;
|
||||||
case 0xCC: ABS CPY CYC(4) break;
|
case 0xCC: ABS CPY CYC(4) break;
|
||||||
case 0xCD: ABS CMP CYC(4) break;
|
case 0xCD: ABS CMP CYC(4) break;
|
||||||
case 0xCE: ABS DECn CYC(5) break;
|
case 0xCE: ABS DEC CYC(6) break;
|
||||||
case 0xCF: $ ABS DCM CYC(6) break; // invalid
|
case 0xCF: $ ABS DCM CYC(6) break;
|
||||||
case 0xD0: REL BNE CYC(2) break;
|
case 0xD0: REL BNE CYC(2) break;
|
||||||
case 0xD1: idy CMP CYC(5) break;
|
case 0xD1: INDY_OPT CMP CYC(5) break;
|
||||||
case 0xD2: $ HLT CYC(2) break;
|
case 0xD2: $ HLT CYC(2) break;
|
||||||
case 0xD3: $ idy DCM CYC(8) break; // invalid
|
case 0xD3: $ INDY_CONST DCM CYC(8) break;
|
||||||
case 0xD4: $ zpx NOP CYC(4) break;
|
case 0xD4: $ zpx NOP CYC(4) break;
|
||||||
case 0xD5: zpx CMP CYC(4) break;
|
case 0xD5: zpx CMP CYC(4) break;
|
||||||
case 0xD6: zpx DECn CYC(6) break;
|
case 0xD6: zpx DEC CYC(6) break;
|
||||||
case 0xD7: $ zpx DCM CYC(6) break; // invalid
|
case 0xD7: $ zpx DCM CYC(6) break;
|
||||||
case 0xD8: CLD CYC(2) break;
|
case 0xD8: CLD CYC(2) break;
|
||||||
case 0xD9: aby CMP CYC(4) break;
|
case 0xD9: ABSY_OPT CMP CYC(4) break;
|
||||||
case 0xDA: $ NOP CYC(2) break;
|
case 0xDA: $ NOP CYC(2) break;
|
||||||
case 0xDB: $ aby DCM CYC(7) break; // invalid
|
case 0xDB: $ ABSY_CONST DCM CYC(7) break;
|
||||||
case 0xDC: $ abx NOP CYC(4) break;
|
case 0xDC: $ ABSX_OPT NOP CYC(4) break;
|
||||||
case 0xDD: abx CMP CYC(4) break;
|
case 0xDD: ABSX_OPT CMP CYC(4) break;
|
||||||
case 0xDE: abx DECn CYC(6) break;
|
case 0xDE: ABSX_CONST DEC CYC(7) break;
|
||||||
case 0xDF: $ abx DCM CYC(7) break; // invalid
|
case 0xDF: $ ABSX_CONST DCM CYC(7) break;
|
||||||
case 0xE0: IMM CPX CYC(2) break;
|
case 0xE0: IMM CPX CYC(2) break;
|
||||||
case 0xE1: idx SBCn CYC(6) break;
|
case 0xE1: idx SBCn CYC(6) break;
|
||||||
case 0xE2: $ IMM NOP CYC(2) break;
|
case 0xE2: $ IMM NOP CYC(2) break;
|
||||||
case 0xE3: $ idx INS CYC(8) break; // invalid
|
case 0xE3: $ idx INS CYC(8) break;
|
||||||
case 0xE4: ZPG CPX CYC(3) break;
|
case 0xE4: ZPG CPX CYC(3) break;
|
||||||
case 0xE5: ZPG SBCn CYC(3) break;
|
case 0xE5: ZPG SBCn CYC(3) break;
|
||||||
case 0xE6: ZPG INCn CYC(5) break;
|
case 0xE6: ZPG INC CYC(5) break;
|
||||||
case 0xE7: $ ZPG INS CYC(5) break; // invalid
|
case 0xE7: $ ZPG INS CYC(5) break;
|
||||||
case 0xE8: INX CYC(2) break;
|
case 0xE8: INX CYC(2) break;
|
||||||
case 0xE9: IMM SBCn CYC(2) break;
|
case 0xE9: IMM SBCn CYC(2) break;
|
||||||
case 0xEA: NOP CYC(2) break;
|
case 0xEA: NOP CYC(2) break;
|
||||||
case 0xEB: $ IMM SBCn CYC(2) break;
|
case 0xEB: $ IMM SBCn CYC(2) break;
|
||||||
case 0xEC: ABS CPX CYC(4) break;
|
case 0xEC: ABS CPX CYC(4) break;
|
||||||
case 0xED: ABS SBCn CYC(4) break;
|
case 0xED: ABS SBCn CYC(4) break;
|
||||||
case 0xEE: ABS INCn CYC(6) break;
|
case 0xEE: ABS INC CYC(6) break;
|
||||||
case 0xEF: $ ABS INS CYC(6) break; // invalid
|
case 0xEF: $ ABS INS CYC(6) break;
|
||||||
case 0xF0: REL BEQ CYC(2) break;
|
case 0xF0: REL BEQ CYC(2) break;
|
||||||
case 0xF1: idy SBCn CYC(5) break;
|
case 0xF1: INDY_OPT SBCn CYC(5) break;
|
||||||
case 0xF2: $ HLT CYC(2) break;
|
case 0xF2: $ HLT CYC(2) break;
|
||||||
case 0xF3: $ idy INS CYC(8) break; // invalid
|
case 0xF3: $ INDY_CONST INS CYC(8) break;
|
||||||
case 0xF4: $ zpx NOP CYC(4) break;
|
case 0xF4: $ zpx NOP CYC(4) break;
|
||||||
case 0xF5: zpx SBCn CYC(4) break;
|
case 0xF5: zpx SBCn CYC(4) break;
|
||||||
case 0xF6: zpx INCn CYC(6) break;
|
case 0xF6: zpx INC CYC(6) break;
|
||||||
case 0xF7: $ zpx INS CYC(6) break; // invalid
|
case 0xF7: $ zpx INS CYC(6) break;
|
||||||
case 0xF8: SED CYC(2) break;
|
case 0xF8: SED CYC(2) break;
|
||||||
case 0xF9: aby SBCn CYC(4) break;
|
case 0xF9: ABSY_OPT SBCn CYC(4) break;
|
||||||
case 0xFA: $ NOP CYC(2) break;
|
case 0xFA: $ NOP CYC(2) break;
|
||||||
case 0xFB: $ aby INS CYC(7) break;
|
case 0xFB: $ ABSY_CONST INS CYC(7) break;
|
||||||
case 0xFC: $ abx NOP CYC(4) break;
|
case 0xFC: $ ABSX_OPT NOP CYC(4) break;
|
||||||
case 0xFD: abx SBCn CYC(4) break;
|
case 0xFD: ABSX_OPT SBCn CYC(4) break;
|
||||||
case 0xFE: abx INCn CYC(6) break;
|
case 0xFE: ABSX_CONST INC CYC(7) break;
|
||||||
case 0xFF: $ abx INS CYC(7) break;
|
case 0xFF: $ ABSX_CONST INS CYC(7) break;
|
||||||
}
|
}
|
||||||
|
#undef $
|
||||||
}
|
}
|
||||||
|
|
||||||
// NTSC_BEGIN
|
// NTSC_BEGIN
|
||||||
|
|
|
@ -38,7 +38,6 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
|
||||||
WORD val;
|
WORD val;
|
||||||
AF_TO_EF
|
AF_TO_EF
|
||||||
ULONG uExecutedCycles = 0;
|
ULONG uExecutedCycles = 0;
|
||||||
BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA)
|
|
||||||
WORD base;
|
WORD base;
|
||||||
g_bDebugBreakpointHit = 0;
|
g_bDebugBreakpointHit = 0;
|
||||||
|
|
||||||
|
@ -52,7 +51,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
|
||||||
ULONG uPreviousCycles = uExecutedCycles;
|
ULONG uPreviousCycles = uExecutedCycles;
|
||||||
// NTSC_END
|
// NTSC_END
|
||||||
|
|
||||||
if (g_ActiveCPU == CPU_Z80)
|
if (GetActiveCpu() == CPU_Z80)
|
||||||
{
|
{
|
||||||
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
|
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
|
||||||
}
|
}
|
||||||
|
@ -61,265 +60,265 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
|
||||||
if (!Fetch(iOpcode, uExecutedCycles))
|
if (!Fetch(iOpcode, uExecutedCycles))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#define $ INV // INV = Invalid -> Debugger Break
|
||||||
switch (iOpcode)
|
switch (iOpcode)
|
||||||
{
|
{
|
||||||
#define $ INV // INV = Invalid -> Debugger Break
|
|
||||||
case 0x00: BRK CYC(7) break;
|
case 0x00: BRK CYC(7) break;
|
||||||
case 0x01: idx ORA CYC(6) break;
|
case 0x01: idx ORA CYC(6) break;
|
||||||
case 0x02: $ IMM NOP CYC(2) break;
|
case 0x02: $ IMM NOP CYC(2) break;
|
||||||
case 0x03: $ NOP CYC(2) break;
|
case 0x03: $ NOP CYC(1) break;
|
||||||
case 0x04: ZPG TSB CYC(5) break;
|
case 0x04: ZPG TSB CYC(5) break;
|
||||||
case 0x05: ZPG ORA CYC(3) break;
|
case 0x05: ZPG ORA CYC(3) break;
|
||||||
case 0x06: ZPG ASLc CYC(5) break;
|
case 0x06: ZPG ASLc CYC(5) break;
|
||||||
case 0x07: $ NOP CYC(2) break;
|
case 0x07: $ NOP CYC(1) break;
|
||||||
case 0x08: PHP CYC(3) break;
|
case 0x08: PHP CYC(3) break;
|
||||||
case 0x09: IMM ORA CYC(2) break;
|
case 0x09: IMM ORA CYC(2) break;
|
||||||
case 0x0A: asl CYC(2) break;
|
case 0x0A: asl CYC(2) break;
|
||||||
case 0x0B: $ NOP CYC(2) break;
|
case 0x0B: $ NOP CYC(1) break;
|
||||||
case 0x0C: ABS TSB CYC(6) break;
|
case 0x0C: ABS TSB CYC(6) break;
|
||||||
case 0x0D: ABS ORA CYC(4) break;
|
case 0x0D: ABS ORA CYC(4) break;
|
||||||
case 0x0E: ABS ASLc CYC(6) break;
|
case 0x0E: ABS ASLc CYC(6) break;
|
||||||
case 0x0F: $ NOP CYC(2) break;
|
case 0x0F: $ NOP CYC(1) break;
|
||||||
case 0x10: REL BPL CYC(2) break;
|
case 0x10: REL BPL CYC(2) break;
|
||||||
case 0x11: idy ORA CYC(5) break;
|
case 0x11: INDY_OPT ORA CYC(5) break;
|
||||||
case 0x12: izp ORA CYC(5) break;
|
case 0x12: izp ORA CYC(5) break;
|
||||||
case 0x13: $ NOP CYC(2) break;
|
case 0x13: $ NOP CYC(1) break;
|
||||||
case 0x14: ZPG TRB CYC(5) break;
|
case 0x14: ZPG TRB CYC(5) break;
|
||||||
case 0x15: zpx ORA CYC(4) break;
|
case 0x15: zpx ORA CYC(4) break;
|
||||||
case 0x16: zpx ASLc CYC(6) break;
|
case 0x16: zpx ASLc CYC(6) break;
|
||||||
case 0x17: $ NOP CYC(2) break;
|
case 0x17: $ NOP CYC(1) break;
|
||||||
case 0x18: CLC CYC(2) break;
|
case 0x18: CLC CYC(2) break;
|
||||||
case 0x19: aby ORA CYC(4) break;
|
case 0x19: ABSY_OPT ORA CYC(4) break;
|
||||||
case 0x1A: INA CYC(2) break;
|
case 0x1A: INA CYC(2) break;
|
||||||
case 0x1B: $ NOP CYC(2) break;
|
case 0x1B: $ NOP CYC(1) break;
|
||||||
case 0x1C: ABS TRB CYC(6) break;
|
case 0x1C: ABS TRB CYC(6) break;
|
||||||
case 0x1D: abx ORA CYC(4) break;
|
case 0x1D: ABSX_OPT ORA CYC(4) break;
|
||||||
case 0x1E: abx ASLc CYC(6) break;
|
case 0x1E: ABSX_OPT ASLc CYC(6) break;
|
||||||
case 0x1F: $ NOP CYC(2) break;
|
case 0x1F: $ NOP CYC(1) break;
|
||||||
case 0x20: ABS JSR CYC(6) break;
|
case 0x20: ABS JSR CYC(6) break;
|
||||||
case 0x21: idx AND CYC(6) break;
|
case 0x21: idx AND CYC(6) break;
|
||||||
case 0x22: $ IMM NOP CYC(2) break;
|
case 0x22: $ IMM NOP CYC(2) break;
|
||||||
case 0x23: $ NOP CYC(2) break;
|
case 0x23: $ NOP CYC(1) break;
|
||||||
case 0x24: ZPG BIT CYC(3) break;
|
case 0x24: ZPG BIT CYC(3) break;
|
||||||
case 0x25: ZPG AND CYC(3) break;
|
case 0x25: ZPG AND CYC(3) break;
|
||||||
case 0x26: ZPG ROLc CYC(5) break;
|
case 0x26: ZPG ROLc CYC(5) break;
|
||||||
case 0x27: $ NOP CYC(2) break;
|
case 0x27: $ NOP CYC(1) break;
|
||||||
case 0x28: PLP CYC(4) break;
|
case 0x28: PLP CYC(4) break;
|
||||||
case 0x29: IMM AND CYC(2) break;
|
case 0x29: IMM AND CYC(2) break;
|
||||||
case 0x2A: rol CYC(2) break;
|
case 0x2A: rol CYC(2) break;
|
||||||
case 0x2B: $ NOP CYC(2) break;
|
case 0x2B: $ NOP CYC(1) break;
|
||||||
case 0x2C: ABS BIT CYC(4) break;
|
case 0x2C: ABS BIT CYC(4) break;
|
||||||
case 0x2D: ABS AND CYC(2) break;
|
case 0x2D: ABS AND CYC(4) break;
|
||||||
case 0x2E: ABS ROLc CYC(6) break;
|
case 0x2E: ABS ROLc CYC(6) break;
|
||||||
case 0x2F: $ NOP CYC(2) break;
|
case 0x2F: $ NOP CYC(1) break;
|
||||||
case 0x30: REL BMI CYC(2) break;
|
case 0x30: REL BMI CYC(2) break;
|
||||||
case 0x31: idy AND CYC(5) break;
|
case 0x31: INDY_OPT AND CYC(5) break;
|
||||||
case 0x32: izp AND CYC(5) break;
|
case 0x32: izp AND CYC(5) break;
|
||||||
case 0x33: $ NOP CYC(2) break;
|
case 0x33: $ NOP CYC(1) break;
|
||||||
case 0x34: zpx BIT CYC(4) break;
|
case 0x34: zpx BIT CYC(4) break;
|
||||||
case 0x35: zpx AND CYC(4) break;
|
case 0x35: zpx AND CYC(4) break;
|
||||||
case 0x36: zpx ROLc CYC(6) break;
|
case 0x36: zpx ROLc CYC(6) break;
|
||||||
case 0x37: $ NOP CYC(2) break;
|
case 0x37: $ NOP CYC(1) break;
|
||||||
case 0x38: SEC CYC(2) break;
|
case 0x38: SEC CYC(2) break;
|
||||||
case 0x39: aby AND CYC(4) break;
|
case 0x39: ABSY_OPT AND CYC(4) break;
|
||||||
case 0x3A: DEA CYC(2) break;
|
case 0x3A: DEA CYC(2) break;
|
||||||
case 0x3B: $ NOP CYC(2) break;
|
case 0x3B: $ NOP CYC(1) break;
|
||||||
case 0x3C: abx BIT CYC(4) break;
|
case 0x3C: ABSX_OPT BIT CYC(4) break;
|
||||||
case 0x3D: abx AND CYC(4) break;
|
case 0x3D: ABSX_OPT AND CYC(4) break;
|
||||||
case 0x3E: abx ROLc CYC(6) break;
|
case 0x3E: ABSX_OPT ROLc CYC(6) break;
|
||||||
case 0x3F: $ NOP CYC(2) break;
|
case 0x3F: $ NOP CYC(1) break;
|
||||||
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
|
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
|
||||||
case 0x41: idx EOR CYC(6) break;
|
case 0x41: idx EOR CYC(6) break;
|
||||||
case 0x42: $ IMM NOP CYC(2) break;
|
case 0x42: $ IMM NOP CYC(2) break;
|
||||||
case 0x43: $ NOP CYC(2) break;
|
case 0x43: $ NOP CYC(1) break;
|
||||||
case 0x44: $ ZPG NOP CYC(3) break;
|
case 0x44: $ ZPG NOP CYC(3) break;
|
||||||
case 0x45: ZPG EOR CYC(3) break;
|
case 0x45: ZPG EOR CYC(3) break;
|
||||||
case 0x46: ZPG LSRc CYC(5) break;
|
case 0x46: ZPG LSRc CYC(5) break;
|
||||||
case 0x47: $ NOP CYC(2) break;
|
case 0x47: $ NOP CYC(1) break;
|
||||||
case 0x48: PHA CYC(3) break;
|
case 0x48: PHA CYC(3) break;
|
||||||
case 0x49: IMM EOR CYC(2) break;
|
case 0x49: IMM EOR CYC(2) break;
|
||||||
case 0x4A: lsr CYC(2) break;
|
case 0x4A: lsr CYC(2) break;
|
||||||
case 0x4B: $ NOP CYC(2) break;
|
case 0x4B: $ NOP CYC(1) break;
|
||||||
case 0x4C: ABS JMP CYC(3) break;
|
case 0x4C: ABS JMP CYC(3) break;
|
||||||
case 0x4D: ABS EOR CYC(4) break;
|
case 0x4D: ABS EOR CYC(4) break;
|
||||||
case 0x4E: ABS LSRc CYC(6) break;
|
case 0x4E: ABS LSRc CYC(6) break;
|
||||||
case 0x4F: $ NOP CYC(2) break;
|
case 0x4F: $ NOP CYC(1) break;
|
||||||
case 0x50: REL BVC CYC(2) break;
|
case 0x50: REL BVC CYC(2) break;
|
||||||
case 0x51: idy EOR CYC(5) break;
|
case 0x51: INDY_OPT EOR CYC(5) break;
|
||||||
case 0x52: izp EOR CYC(5) break;
|
case 0x52: izp EOR CYC(5) break;
|
||||||
case 0x53: $ NOP CYC(2) break;
|
case 0x53: $ NOP CYC(1) break;
|
||||||
case 0x54: $ zpx NOP CYC(4) break;
|
case 0x54: $ zpx NOP CYC(4) break;
|
||||||
case 0x55: zpx EOR CYC(4) break;
|
case 0x55: zpx EOR CYC(4) break;
|
||||||
case 0x56: zpx LSRc CYC(6) break;
|
case 0x56: zpx LSRc CYC(6) break;
|
||||||
case 0x57: $ NOP CYC(2) break;
|
case 0x57: $ NOP CYC(1) break;
|
||||||
case 0x58: CLI CYC(2) break;
|
case 0x58: CLI CYC(2) break;
|
||||||
case 0x59: aby EOR CYC(4) break;
|
case 0x59: ABSY_OPT EOR CYC(4) break;
|
||||||
case 0x5A: PHY CYC(3) break;
|
case 0x5A: PHY CYC(3) break;
|
||||||
case 0x5B: $ NOP CYC(2) break;
|
case 0x5B: $ NOP CYC(1) break;
|
||||||
case 0x5C: $ abx NOP CYC(8) break;
|
case 0x5C: $ ABS NOP CYC(8) break;
|
||||||
case 0x5D: abx EOR CYC(4) break;
|
case 0x5D: ABSX_OPT EOR CYC(4) break;
|
||||||
case 0x5E: abx LSRc CYC(6) break;
|
case 0x5E: ABSX_OPT LSRc CYC(6) break;
|
||||||
case 0x5F: $ NOP CYC(2) break;
|
case 0x5F: $ NOP CYC(1) break;
|
||||||
case 0x60: RTS CYC(6) break;
|
case 0x60: RTS CYC(6) break;
|
||||||
case 0x61: idx ADCc CYC(6) break;
|
case 0x61: idx ADCc CYC(6) break;
|
||||||
case 0x62: $ IMM NOP CYC(2) break;
|
case 0x62: $ IMM NOP CYC(2) break;
|
||||||
case 0x63: $ NOP CYC(2) break;
|
case 0x63: $ NOP CYC(1) break;
|
||||||
case 0x64: ZPG STZ CYC(3) break;
|
case 0x64: ZPG STZ CYC(3) break;
|
||||||
case 0x65: ZPG ADCc CYC(3) break;
|
case 0x65: ZPG ADCc CYC(3) break;
|
||||||
case 0x66: ZPG RORc CYC(5) break;
|
case 0x66: ZPG RORc CYC(5) break;
|
||||||
case 0x67: $ NOP CYC(2) break;
|
case 0x67: $ NOP CYC(1) break;
|
||||||
case 0x68: PLA CYC(4) break;
|
case 0x68: PLA CYC(4) break;
|
||||||
case 0x69: IMM ADCc CYC(2) break;
|
case 0x69: IMM ADCc CYC(2) break;
|
||||||
case 0x6A: ror CYC(2) break;
|
case 0x6A: ror CYC(2) break;
|
||||||
case 0x6B: $ NOP CYC(2) break;
|
case 0x6B: $ NOP CYC(1) break;
|
||||||
case 0x6C: IABSCMOS JMP CYC(6) break;
|
case 0x6C: IABS_CMOS JMP CYC(6) break;
|
||||||
case 0x6D: ABS ADCc CYC(4) break;
|
case 0x6D: ABS ADCc CYC(4) break;
|
||||||
case 0x6E: ABS RORc CYC(6) break;
|
case 0x6E: ABS RORc CYC(6) break;
|
||||||
case 0x6F: $ NOP CYC(2) break;
|
case 0x6F: $ NOP CYC(1) break;
|
||||||
case 0x70: REL BVS CYC(2) break;
|
case 0x70: REL BVS CYC(2) break;
|
||||||
case 0x71: idy ADCc CYC(5) break;
|
case 0x71: INDY_OPT ADCc CYC(5) break;
|
||||||
case 0x72: izp ADCc CYC(5) break;
|
case 0x72: izp ADCc CYC(5) break;
|
||||||
case 0x73: $ NOP CYC(2) break;
|
case 0x73: $ NOP CYC(1) break;
|
||||||
case 0x74: zpx STZ CYC(4) break;
|
case 0x74: zpx STZ CYC(4) break;
|
||||||
case 0x75: zpx ADCc CYC(4) break;
|
case 0x75: zpx ADCc CYC(4) break;
|
||||||
case 0x76: zpx RORc CYC(6) break;
|
case 0x76: zpx RORc CYC(6) break;
|
||||||
case 0x77: $ NOP CYC(2) break;
|
case 0x77: $ NOP CYC(1) break;
|
||||||
case 0x78: SEI CYC(2) break;
|
case 0x78: SEI CYC(2) break;
|
||||||
case 0x79: aby ADCc CYC(4) break;
|
case 0x79: ABSY_OPT ADCc CYC(4) break;
|
||||||
case 0x7A: PLY CYC(4) break;
|
case 0x7A: PLY CYC(4) break;
|
||||||
case 0x7B: $ NOP CYC(2) break;
|
case 0x7B: $ NOP CYC(1) break;
|
||||||
case 0x7C: IABSX JMP CYC(6) break; //
|
case 0x7C: IABSX JMP CYC(6) break;
|
||||||
case 0x7D: abx ADCc CYC(4) break;
|
case 0x7D: ABSX_OPT ADCc CYC(4) break;
|
||||||
case 0x7E: abx RORc CYC(6) break;
|
case 0x7E: ABSX_OPT RORc CYC(6) break;
|
||||||
case 0x7F: $ NOP CYC(2) break;
|
case 0x7F: $ NOP CYC(1) break;
|
||||||
case 0x80: REL BRA CYC(2) break;
|
case 0x80: REL BRA CYC(2) break;
|
||||||
case 0x81: idx STA CYC(6) break;
|
case 0x81: idx STA CYC(6) break;
|
||||||
case 0x82: $ IMM NOP CYC(2) break;
|
case 0x82: $ IMM NOP CYC(2) break;
|
||||||
case 0x83: $ NOP CYC(2) break;
|
case 0x83: $ NOP CYC(1) break;
|
||||||
case 0x84: ZPG STY CYC(3) break;
|
case 0x84: ZPG STY CYC(3) break;
|
||||||
case 0x85: ZPG STA CYC(3) break;
|
case 0x85: ZPG STA CYC(3) break;
|
||||||
case 0x86: ZPG STX CYC(3) break;
|
case 0x86: ZPG STX CYC(3) break;
|
||||||
case 0x87: $ NOP CYC(2) break;
|
case 0x87: $ NOP CYC(1) break;
|
||||||
case 0x88: DEY CYC(2) break;
|
case 0x88: DEY CYC(2) break;
|
||||||
case 0x89: IMM BITI CYC(2) break;
|
case 0x89: IMM BITI CYC(2) break;
|
||||||
case 0x8A: TXA CYC(2) break;
|
case 0x8A: TXA CYC(2) break;
|
||||||
case 0x8B: $ NOP CYC(2) break;
|
case 0x8B: $ NOP CYC(1) break;
|
||||||
case 0x8C: ABS STY CYC(4) break;
|
case 0x8C: ABS STY CYC(4) break;
|
||||||
case 0x8D: ABS STA CYC(4) break;
|
case 0x8D: ABS STA CYC(4) break;
|
||||||
case 0x8E: ABS STX CYC(4) break;
|
case 0x8E: ABS STX CYC(4) break;
|
||||||
case 0x8F: $ NOP CYC(2) break;
|
case 0x8F: $ NOP CYC(1) break;
|
||||||
case 0x90: REL BCC CYC(2) break;
|
case 0x90: REL BCC CYC(2) break;
|
||||||
case 0x91: idy STA CYC(6) break;
|
case 0x91: INDY_CONST STA CYC(6) break;
|
||||||
case 0x92: izp STA CYC(5) break;
|
case 0x92: izp STA CYC(5) break;
|
||||||
case 0x93: $ NOP CYC(2) break;
|
case 0x93: $ NOP CYC(1) break;
|
||||||
case 0x94: zpx STY CYC(4) break;
|
case 0x94: zpx STY CYC(4) break;
|
||||||
case 0x95: zpx STA CYC(4) break;
|
case 0x95: zpx STA CYC(4) break;
|
||||||
case 0x96: zpy STX CYC(4) break;
|
case 0x96: zpy STX CYC(4) break;
|
||||||
case 0x97: $ NOP CYC(2) break;
|
case 0x97: $ NOP CYC(1) break;
|
||||||
case 0x98: TYA CYC(2) break;
|
case 0x98: TYA CYC(2) break;
|
||||||
case 0x99: aby STA CYC(5) break;
|
case 0x99: ABSY_CONST STA CYC(5) break;
|
||||||
case 0x9A: TXS CYC(2) break;
|
case 0x9A: TXS CYC(2) break;
|
||||||
case 0x9B: $ NOP CYC(2) break;
|
case 0x9B: $ NOP CYC(1) break;
|
||||||
case 0x9C: ABS STZ CYC(4) break;
|
case 0x9C: ABS STZ CYC(4) break;
|
||||||
case 0x9D: abx STA CYC(5) break;
|
case 0x9D: ABSX_CONST STA CYC(5) break;
|
||||||
case 0x9E: abx STZ CYC(5) break;
|
case 0x9E: ABSX_CONST STZ CYC(5) break;
|
||||||
case 0x9F: $ NOP CYC(2) break;
|
case 0x9F: $ NOP CYC(1) break;
|
||||||
case 0xA0: IMM LDY CYC(2) break;
|
case 0xA0: IMM LDY CYC(2) break;
|
||||||
case 0xA1: idx LDA CYC(6) break;
|
case 0xA1: idx LDA CYC(6) break;
|
||||||
case 0xA2: IMM LDX CYC(2) break;
|
case 0xA2: IMM LDX CYC(2) break;
|
||||||
case 0xA3: $ NOP CYC(2) break;
|
case 0xA3: $ NOP CYC(1) break;
|
||||||
case 0xA4: ZPG LDY CYC(3) break;
|
case 0xA4: ZPG LDY CYC(3) break;
|
||||||
case 0xA5: ZPG LDA CYC(3) break;
|
case 0xA5: ZPG LDA CYC(3) break;
|
||||||
case 0xA6: ZPG LDX CYC(3) break;
|
case 0xA6: ZPG LDX CYC(3) break;
|
||||||
case 0xA7: $ NOP CYC(2) break;
|
case 0xA7: $ NOP CYC(1) break;
|
||||||
case 0xA8: TAY CYC(2) break;
|
case 0xA8: TAY CYC(2) break;
|
||||||
case 0xA9: IMM LDA CYC(2) break;
|
case 0xA9: IMM LDA CYC(2) break;
|
||||||
case 0xAA: TAX CYC(2) break;
|
case 0xAA: TAX CYC(2) break;
|
||||||
case 0xAB: $ NOP CYC(2) break;
|
case 0xAB: $ NOP CYC(1) break;
|
||||||
case 0xAC: ABS LDY CYC(4) break;
|
case 0xAC: ABS LDY CYC(4) break;
|
||||||
case 0xAD: ABS LDA CYC(4) break;
|
case 0xAD: ABS LDA CYC(4) break;
|
||||||
case 0xAE: ABS LDX CYC(4) break;
|
case 0xAE: ABS LDX CYC(4) break;
|
||||||
case 0xAF: $ NOP CYC(2) break;
|
case 0xAF: $ NOP CYC(1) break;
|
||||||
case 0xB0: REL BCS CYC(2) break;
|
case 0xB0: REL BCS CYC(2) break;
|
||||||
case 0xB1: idy LDA CYC(5) break;
|
case 0xB1: INDY_OPT LDA CYC(5) break;
|
||||||
case 0xB2: izp LDA CYC(5) break;
|
case 0xB2: izp LDA CYC(5) break;
|
||||||
case 0xB3: $ NOP CYC(2) break;
|
case 0xB3: $ NOP CYC(1) break;
|
||||||
case 0xB4: zpx LDY CYC(4) break;
|
case 0xB4: zpx LDY CYC(4) break;
|
||||||
case 0xB5: zpx LDA CYC(4) break;
|
case 0xB5: zpx LDA CYC(4) break;
|
||||||
case 0xB6: zpy LDX CYC(4) break;
|
case 0xB6: zpy LDX CYC(4) break;
|
||||||
case 0xB7: $ NOP CYC(2) break;
|
case 0xB7: $ NOP CYC(1) break;
|
||||||
case 0xB8: CLV CYC(2) break;
|
case 0xB8: CLV CYC(2) break;
|
||||||
case 0xB9: aby LDA CYC(4) break;
|
case 0xB9: ABSY_OPT LDA CYC(4) break;
|
||||||
case 0xBA: TSX CYC(2) break;
|
case 0xBA: TSX CYC(2) break;
|
||||||
case 0xBB: $ NOP CYC(2) break;
|
case 0xBB: $ NOP CYC(1) break;
|
||||||
case 0xBC: abx LDY CYC(4) break;
|
case 0xBC: ABSX_OPT LDY CYC(4) break;
|
||||||
case 0xBD: abx LDA CYC(4) break;
|
case 0xBD: ABSX_OPT LDA CYC(4) break;
|
||||||
case 0xBE: aby LDX CYC(4) break;
|
case 0xBE: ABSY_OPT LDX CYC(4) break;
|
||||||
case 0xBF: $ NOP CYC(2) break;
|
case 0xBF: $ NOP CYC(1) break;
|
||||||
case 0xC0: IMM CPY CYC(2) break;
|
case 0xC0: IMM CPY CYC(2) break;
|
||||||
case 0xC1: idx CMP CYC(6) break;
|
case 0xC1: idx CMP CYC(6) break;
|
||||||
case 0xC2: $ IMM NOP CYC(2) break;
|
case 0xC2: $ IMM NOP CYC(2) break;
|
||||||
case 0xC3: $ NOP CYC(2) break;
|
case 0xC3: $ NOP CYC(1) break;
|
||||||
case 0xC4: ZPG CPY CYC(3) break;
|
case 0xC4: ZPG CPY CYC(3) break;
|
||||||
case 0xC5: ZPG CMP CYC(3) break;
|
case 0xC5: ZPG CMP CYC(3) break;
|
||||||
case 0xC6: ZPG DECc CYC(5) break;
|
case 0xC6: ZPG DEC CYC(5) break;
|
||||||
case 0xC7: $ NOP CYC(2) break;
|
case 0xC7: $ NOP CYC(1) break;
|
||||||
case 0xC8: INY CYC(2) break;
|
case 0xC8: INY CYC(2) break;
|
||||||
case 0xC9: IMM CMP CYC(2) break;
|
case 0xC9: IMM CMP CYC(2) break;
|
||||||
case 0xCA: DEX CYC(2) break;
|
case 0xCA: DEX CYC(2) break;
|
||||||
case 0xCB: $ NOP CYC(2) break;
|
case 0xCB: $ NOP CYC(1) break;
|
||||||
case 0xCC: ABS CPY CYC(4) break;
|
case 0xCC: ABS CPY CYC(4) break;
|
||||||
case 0xCD: ABS CMP CYC(4) break;
|
case 0xCD: ABS CMP CYC(4) break;
|
||||||
case 0xCE: ABS DECc CYC(5) break;
|
case 0xCE: ABS DEC CYC(6) break;
|
||||||
case 0xCF: $ NOP CYC(2) break;
|
case 0xCF: $ NOP CYC(1) break;
|
||||||
case 0xD0: REL BNE CYC(2) break;
|
case 0xD0: REL BNE CYC(2) break;
|
||||||
case 0xD1: idy CMP CYC(5) break;
|
case 0xD1: INDY_OPT CMP CYC(5) break;
|
||||||
case 0xD2: izp CMP CYC(5) break;
|
case 0xD2: izp CMP CYC(5) break;
|
||||||
case 0xD3: $ NOP CYC(2) break;
|
case 0xD3: $ NOP CYC(1) break;
|
||||||
case 0xD4: $ zpx NOP CYC(4) break;
|
case 0xD4: $ zpx NOP CYC(4) break;
|
||||||
case 0xD5: zpx CMP CYC(4) break;
|
case 0xD5: zpx CMP CYC(4) break;
|
||||||
case 0xD6: zpx DECc CYC(6) break;
|
case 0xD6: zpx DEC CYC(6) break;
|
||||||
case 0xD7: $ NOP CYC(2) break;
|
case 0xD7: $ NOP CYC(1) break;
|
||||||
case 0xD8: CLD CYC(2) break;
|
case 0xD8: CLD CYC(2) break;
|
||||||
case 0xD9: aby CMP CYC(4) break;
|
case 0xD9: ABSY_OPT CMP CYC(4) break;
|
||||||
case 0xDA: PHX CYC(3) break;
|
case 0xDA: PHX CYC(3) break;
|
||||||
case 0xDB: $ NOP CYC(2) break;
|
case 0xDB: $ NOP CYC(1) break;
|
||||||
case 0xDC: $ abx NOP CYC(4) break;
|
case 0xDC: $ ABS LDD CYC(4) break;
|
||||||
case 0xDD: abx CMP CYC(4) break;
|
case 0xDD: ABSX_OPT CMP CYC(4) break;
|
||||||
case 0xDE: abx DECc CYC(6) break;
|
case 0xDE: ABSX_CONST DEC CYC(7) break;
|
||||||
case 0xDF: $ NOP CYC(2) break;
|
case 0xDF: $ NOP CYC(1) break;
|
||||||
case 0xE0: IMM CPX CYC(2) break;
|
case 0xE0: IMM CPX CYC(2) break;
|
||||||
case 0xE1: idx SBCc CYC(6) break;
|
case 0xE1: idx SBCc CYC(6) break;
|
||||||
case 0xE2: $ IMM NOP CYC(2) break;
|
case 0xE2: $ IMM NOP CYC(2) break;
|
||||||
case 0xE3: $ NOP CYC(2) break;
|
case 0xE3: $ NOP CYC(1) break;
|
||||||
case 0xE4: ZPG CPX CYC(3) break;
|
case 0xE4: ZPG CPX CYC(3) break;
|
||||||
case 0xE5: ZPG SBCc CYC(3) break;
|
case 0xE5: ZPG SBCc CYC(3) break;
|
||||||
case 0xE6: ZPG INCc CYC(5) break;
|
case 0xE6: ZPG INC CYC(5) break;
|
||||||
case 0xE7: $ NOP CYC(2) break;
|
case 0xE7: $ NOP CYC(1) break;
|
||||||
case 0xE8: INX CYC(2) break;
|
case 0xE8: INX CYC(2) break;
|
||||||
case 0xE9: IMM SBCc CYC(2) break;
|
case 0xE9: IMM SBCc CYC(2) break;
|
||||||
case 0xEA: NOP CYC(2) break;
|
case 0xEA: NOP CYC(2) break;
|
||||||
case 0xEB: $ NOP CYC(2) break;
|
case 0xEB: $ NOP CYC(1) break;
|
||||||
case 0xEC: ABS CPX CYC(4) break;
|
case 0xEC: ABS CPX CYC(4) break;
|
||||||
case 0xED: ABS SBCc CYC(4) break;
|
case 0xED: ABS SBCc CYC(4) break;
|
||||||
case 0xEE: ABS INCc CYC(6) break;
|
case 0xEE: ABS INC CYC(6) break;
|
||||||
case 0xEF: $ NOP CYC(2) break;
|
case 0xEF: $ NOP CYC(1) break;
|
||||||
case 0xF0: REL BEQ CYC(2) break;
|
case 0xF0: REL BEQ CYC(2) break;
|
||||||
case 0xF1: idy SBCc CYC(5) break;
|
case 0xF1: INDY_OPT SBCc CYC(5) break;
|
||||||
case 0xF2: izp SBCc CYC(5) break;
|
case 0xF2: izp SBCc CYC(5) break;
|
||||||
case 0xF3: $ NOP CYC(2) break;
|
case 0xF3: $ NOP CYC(1) break;
|
||||||
case 0xF4: $ zpx NOP CYC(4) break;
|
case 0xF4: $ zpx NOP CYC(4) break;
|
||||||
case 0xF5: zpx SBCc CYC(4) break;
|
case 0xF5: zpx SBCc CYC(4) break;
|
||||||
case 0xF6: zpx INCc CYC(6) break;
|
case 0xF6: zpx INC CYC(6) break;
|
||||||
case 0xF7: $ NOP CYC(2) break;
|
case 0xF7: $ NOP CYC(1) break;
|
||||||
case 0xF8: SED CYC(2) break;
|
case 0xF8: SED CYC(2) break;
|
||||||
case 0xF9: aby SBCc CYC(4) break;
|
case 0xF9: ABSY_OPT SBCc CYC(4) break;
|
||||||
case 0xFA: PLX CYC(4) break;
|
case 0xFA: PLX CYC(4) break;
|
||||||
case 0xFB: $ NOP CYC(2) break;
|
case 0xFB: $ NOP CYC(1) break;
|
||||||
case 0xFC: $ abx NOP CYC(4) break;
|
case 0xFC: $ ABS LDD CYC(4) break;
|
||||||
case 0xFD: abx SBCc CYC(4) break;
|
case 0xFD: ABSX_OPT SBCc CYC(4) break;
|
||||||
case 0xFE: abx INCc CYC(6) break;
|
case 0xFE: ABSX_CONST INC CYC(7) break;
|
||||||
case 0xFF: $ NOP CYC(2) break;
|
case 0xFF: $ NOP CYC(1) break;
|
||||||
}
|
}
|
||||||
#undef $
|
#undef $
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@ along with AppleWin; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef unsigned char u8;
|
typedef unsigned char u8; // TODO: change to <stdint.h> uint8_t
|
||||||
typedef unsigned short u16;
|
typedef unsigned short u16; // TODO: change to <stdint.h> uint16_t
|
||||||
|
|
||||||
// return (x < 255) ? (x+1) : 255;
|
// return (x < 255) ? (x+1) : 255;
|
||||||
inline u8 IncClamp8( u8 x )
|
inline u8 IncClamp8( u8 x )
|
||||||
|
@ -37,36 +37,51 @@ inline u8 DecClamp8( u8 x )
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Verify: RGBA or BGRA (.bmp format)
|
||||||
// 0 A n/a
|
// 0 A n/a
|
||||||
// 1 B Exec
|
// 1 B Exec
|
||||||
// 2 G Read
|
// 2 G Read
|
||||||
// 3 R Write
|
// 3 R Write
|
||||||
// RGBA r= write, g = read, b = pc
|
//
|
||||||
int g_aMemoryAccess[ 65536 ];
|
// 0xAARRGGBB
|
||||||
u8 *g_pRead = 0;
|
// [0] B Exec
|
||||||
u8 *g_pWrite = 0;
|
// [1] G Load
|
||||||
u8 *g_pExeec = 0;
|
// [2] R Store
|
||||||
|
// [3] A n/a
|
||||||
|
// RGBA r = write, g = read, b = Program Counter
|
||||||
|
const int HEATMAP_W_MASK = 0x00FF0000; // Red Store
|
||||||
|
const int HEATMAP_R_MASK = 0x0000FF00; // Green Load
|
||||||
|
const int HEATMAP_X_MASK = 0x000000FF; // Blue Exec
|
||||||
|
|
||||||
|
|
||||||
|
// This is a memory heatmap
|
||||||
|
// FF = accessed on this clock cycle
|
||||||
|
// FE = accessed 1 clock cycles ago
|
||||||
|
// FD = accessed 2 clock cycles ago
|
||||||
|
// etc.
|
||||||
|
// Displayed as 256x256 64K memory access
|
||||||
|
int g_aMemoryHeatmap[ 65536 ]; // TODO: Change to <stdint.h> int32_t
|
||||||
|
|
||||||
|
#define HEATMAP_W(addr) g_aMemoryHeatmap[ addr ] |= HEATMAP_W_MASK
|
||||||
|
#define HEATMAP_R(addr) g_aMemoryHeatmap[ addr ] |= HEATMAP_R_MASK
|
||||||
|
#define HEATMAP_X(addr) g_aMemoryHeatmap[ addr ] |= HEATMAP_X_MASK
|
||||||
|
|
||||||
#undef READ
|
#undef READ
|
||||||
#define READ ReadByte( addr, uExecutedCycles )
|
#define READ ReadByte( addr, uExecutedCycles )
|
||||||
|
|
||||||
inline u8 ReadByte( u16 addr, int uExecutedCycles )
|
inline u8 ReadByte( u16 addr, int uExecutedCycles )
|
||||||
{
|
{
|
||||||
(u8*) g_pRead = ((u8*)g_aMemoryAccess) + (addr * 4) + 3;
|
// TODO: We should have a single g_bDebuggerActive so we can have a single implementation across ][+ //e
|
||||||
*g_pRead = IncClamp8( *g_pRead );
|
HEATMAP_R(addr);
|
||||||
|
|
||||||
return
|
return ((addr & 0xF000) == 0xC000)
|
||||||
( \
|
? IORead[(addr>>4) & 0xFF](regs.pc,addr,0,0,uExecutedCycles)
|
||||||
((addr & 0xF000) == 0xC000) \
|
: *(mem+addr);
|
||||||
? IORead[(addr>>4) & 0xFF](regs.pc,addr,0,0,uExecutedCycles) \
|
|
||||||
: *(mem+addr) \
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef WRITE
|
#undef WRITE
|
||||||
#define WRITE(a) \
|
#define WRITE(a) \
|
||||||
(u8*) g_pWrite = ((u8*)g_aMemoryAccess) + (addr * 4) + 0; \
|
HEATMAP_W(addr); \
|
||||||
*g_pWrite = DecClamp8( *g_pWrite ); \
|
|
||||||
{ \
|
{ \
|
||||||
memdirty[addr >> 8] = 0xFF; \
|
memdirty[addr >> 8] = 0xFF; \
|
||||||
LPBYTE page = memwrite[addr >> 8]; \
|
LPBYTE page = memwrite[addr >> 8]; \
|
||||||
|
@ -97,7 +112,6 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
WORD val;
|
WORD val;
|
||||||
AF_TO_EF
|
AF_TO_EF
|
||||||
ULONG uExecutedCycles = 0;
|
ULONG uExecutedCycles = 0;
|
||||||
BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA)
|
|
||||||
WORD base;
|
WORD base;
|
||||||
g_bDebugBreakpointHit = 0;
|
g_bDebugBreakpointHit = 0;
|
||||||
|
|
||||||
|
@ -111,12 +125,14 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
ULONG uPreviousCycles = uExecutedCycles;
|
ULONG uPreviousCycles = uExecutedCycles;
|
||||||
// NTSC_END
|
// NTSC_END
|
||||||
|
|
||||||
if (g_ActiveCPU == CPU_Z80)
|
if (GetActiveCpu() == CPU_Z80)
|
||||||
{
|
{
|
||||||
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
|
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
||||||
|
HEATMAP_X( regs.pc );
|
||||||
|
|
||||||
if (!Fetch(iOpcode, uExecutedCycles))
|
if (!Fetch(iOpcode, uExecutedCycles))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -131,267 +147,6 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
{
|
{
|
||||||
// TODO Optimization Note: ?? Move CYC(#) to array ??
|
// TODO Optimization Note: ?? Move CYC(#) to array ??
|
||||||
|
|
||||||
// Version 1 opcode: INV AM Instruction // Form1: INV=DebugBreak AM=AddressingMode
|
|
||||||
// INV Instruction // Form2:
|
|
||||||
//! ! ! ! ! ! // Tab-Stops
|
|
||||||
/*
|
|
||||||
case 0x00: BRK CYC(7) break;
|
|
||||||
case 0x01: idx ORA CYC(6) break;
|
|
||||||
case 0x02: INV IMM NOP CYC(2) break;
|
|
||||||
case 0x03: INV NOP CYC(2) break;
|
|
||||||
case 0x04: ZPG TSB CYC(5) break;
|
|
||||||
case 0x05: ZPG ORA CYC(3) break;
|
|
||||||
case 0x06: ZPG ASL_CMOS CYC(5) break;
|
|
||||||
case 0x07: INV NOP CYC(2) break;
|
|
||||||
case 0x08: PHP CYC(3) break;
|
|
||||||
case 0x09: IMM ORA CYC(2) break;
|
|
||||||
case 0x0A: asl CYC(2) break;
|
|
||||||
case 0x0B: INV NOP CYC(2) break;
|
|
||||||
case 0x0C: ABS TSB CYC(6) break;
|
|
||||||
case 0x0D: ABS ORA CYC(4) break;
|
|
||||||
case 0x0E: ABS ASL_CMOS CYC(6) break;
|
|
||||||
case 0x0F: INV NOP CYC(2) break;
|
|
||||||
case 0x10: REL BPL CYC(2) break;
|
|
||||||
case 0x11: idy ORA CYC(5) break;
|
|
||||||
case 0x12: izp ORA CYC(5) break;
|
|
||||||
case 0x13: INV NOP CYC(2) break;
|
|
||||||
case 0x14: ZPG TRB CYC(5) break;
|
|
||||||
case 0x15: zpx ORA CYC(4) break;
|
|
||||||
case 0x16: zpx ASL_CMOS CYC(6) break;
|
|
||||||
case 0x17: INV NOP CYC(2) break;
|
|
||||||
case 0x18: CLC CYC(2) break;
|
|
||||||
case 0x19: aby ORA CYC(4) break;
|
|
||||||
case 0x1A: INA CYC(2) break;
|
|
||||||
case 0x1B: INV NOP CYC(2) break;
|
|
||||||
case 0x1C: ABS TRB CYC(6) break;
|
|
||||||
case 0x1D: abx ORA CYC(4) break;
|
|
||||||
case 0x1E: abx ASL_CMOS CYC(6) break;
|
|
||||||
case 0x1F: INV NOP CYC(2) break;
|
|
||||||
case 0x20: ABS JSR CYC(6) break;
|
|
||||||
case 0x21: idx AND CYC(6) break;
|
|
||||||
case 0x22: INV IMM NOP CYC(2) break;
|
|
||||||
case 0x23: INV NOP CYC(2) break;
|
|
||||||
case 0x24: ZPG BIT CYC(3) break;
|
|
||||||
case 0x25: ZPG AND CYC(3) break;
|
|
||||||
case 0x26: ZPG ROL_CMOS CYC(5) break;
|
|
||||||
case 0x27: INV NOP CYC(2) break;
|
|
||||||
case 0x28: PLP CYC(4) break;
|
|
||||||
case 0x29: IMM AND CYC(2) break;
|
|
||||||
case 0x2A: rol CYC(2) break;
|
|
||||||
case 0x2B: INV NOP CYC(2) break;
|
|
||||||
case 0x2C: ABS BIT CYC(4) break;
|
|
||||||
case 0x2D: ABS AND CYC(2) break;
|
|
||||||
case 0x2E: ABS ROL_CMOS CYC(6) break;
|
|
||||||
case 0x2F: INV NOP CYC(2) break;
|
|
||||||
case 0x30: REL BMI CYC(2) break;
|
|
||||||
case 0x31: idy AND CYC(5) break;
|
|
||||||
case 0x32: izp AND CYC(5) break;
|
|
||||||
case 0x33: INV NOP CYC(2) break;
|
|
||||||
case 0x34: zpx BIT CYC(4) break;
|
|
||||||
case 0x35: zpx AND CYC(4) break;
|
|
||||||
case 0x36: zpx ROL_CMOS CYC(6) break;
|
|
||||||
case 0x37: INV NOP CYC(2) break;
|
|
||||||
case 0x38: SEC CYC(2) break;
|
|
||||||
case 0x39: aby AND CYC(4) break;
|
|
||||||
case 0x3A: DEA CYC(2) break;
|
|
||||||
case 0x3B: INV NOP CYC(2) break;
|
|
||||||
case 0x3C: abx BIT CYC(4) break;
|
|
||||||
case 0x3D: abx AND CYC(4) break;
|
|
||||||
case 0x3E: abx ROL_CMOS CYC(6) break;
|
|
||||||
case 0x3F: INV NOP CYC(2) break;
|
|
||||||
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
|
|
||||||
case 0x41: idx EOR CYC(6) break;
|
|
||||||
case 0x42: INV IMM NOP CYC(2) break;
|
|
||||||
case 0x43: INV NOP CYC(2) break;
|
|
||||||
case 0x44: INV ZPG NOP CYC(3) break;
|
|
||||||
case 0x45: ZPG EOR CYC(3) break;
|
|
||||||
case 0x46: ZPG LSR_CMOS CYC(5) break;
|
|
||||||
case 0x47: INV NOP CYC(2) break;
|
|
||||||
case 0x48: PHA CYC(3) break;
|
|
||||||
case 0x49: IMM EOR CYC(2) break;
|
|
||||||
case 0x4A: lsr CYC(2) break;
|
|
||||||
case 0x4B: INV NOP CYC(2) break;
|
|
||||||
case 0x4C: ABS JMP CYC(3) break;
|
|
||||||
case 0x4D: ABS EOR CYC(4) break;
|
|
||||||
case 0x4E: ABS LSR_CMOS CYC(6) break;
|
|
||||||
case 0x4F: INV NOP CYC(2) break;
|
|
||||||
case 0x50: REL BVC CYC(2) break;
|
|
||||||
case 0x51: idy EOR CYC(5) break;
|
|
||||||
case 0x52: izp EOR CYC(5) break;
|
|
||||||
case 0x53: INV NOP CYC(2) break;
|
|
||||||
case 0x54: INV zpx NOP CYC(4) break;
|
|
||||||
case 0x55: zpx EOR CYC(4) break;
|
|
||||||
case 0x56: zpx LSR_CMOS CYC(6) break;
|
|
||||||
case 0x57: INV NOP CYC(2) break;
|
|
||||||
case 0x58: CLI CYC(2) break;
|
|
||||||
case 0x59: aby EOR CYC(4) break;
|
|
||||||
case 0x5A: PHY CYC(3) break;
|
|
||||||
case 0x5B: INV NOP CYC(2) break;
|
|
||||||
case 0x5C: INV abx NOP CYC(8) break;
|
|
||||||
case 0x5D: abx EOR CYC(4) break;
|
|
||||||
case 0x5E: abx LSR_CMOS CYC(6) break;
|
|
||||||
case 0x5F: INV NOP CYC(2) break;
|
|
||||||
case 0x60: RTS CYC(6) break;
|
|
||||||
case 0x61: idx ADC_CMOS CYC(6) break;
|
|
||||||
case 0x62: INV IMM NOP CYC(2) break;
|
|
||||||
case 0x63: INV NOP CYC(2) break;
|
|
||||||
case 0x64: ZPG STZ CYC(3) break;
|
|
||||||
case 0x65: ZPG ADC_CMOS CYC(3) break;
|
|
||||||
case 0x66: ZPG ROR_CMOS CYC(5) break;
|
|
||||||
case 0x67: INV NOP CYC(2) break;
|
|
||||||
case 0x68: PLA CYC(4) break;
|
|
||||||
case 0x69: IMM ADC_CMOS CYC(2) break;
|
|
||||||
case 0x6A: ror CYC(2) break;
|
|
||||||
case 0x6B: INV NOP CYC(2) break;
|
|
||||||
case 0x6C: IABSCMOS JMP CYC(6) break; // 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP
|
|
||||||
case 0x6D: ABS ADC_CMOS CYC(4) break;
|
|
||||||
case 0x6E: ABS ROR_CMOS CYC(6) break;
|
|
||||||
case 0x6F: INV NOP CYC(2) break;
|
|
||||||
case 0x70: REL BVS CYC(2) break;
|
|
||||||
case 0x71: idy ADC_CMOS CYC(5) break;
|
|
||||||
case 0x72: izp ADC_CMOS CYC(5) break;
|
|
||||||
case 0x73: INV NOP CYC(2) break;
|
|
||||||
case 0x74: zpx STZ CYC(4) break;
|
|
||||||
case 0x75: zpx ADC_CMOS CYC(4) break;
|
|
||||||
case 0x76: zpx ROR_CMOS CYC(6) break;
|
|
||||||
case 0x77: INV NOP CYC(2) break;
|
|
||||||
case 0x78: SEI CYC(2) break;
|
|
||||||
case 0x79: aby ADC_CMOS CYC(4) break;
|
|
||||||
case 0x7A: PLY CYC(4) break;
|
|
||||||
case 0x7B: INV NOP CYC(2) break;
|
|
||||||
case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP
|
|
||||||
case 0x7D: abx ADC_CMOS CYC(4) break;
|
|
||||||
case 0x7E: abx ROR_CMOS CYC(6) break;
|
|
||||||
case 0x7F: INV NOP CYC(2) break;
|
|
||||||
case 0x80: REL BRA CYC(2) break;
|
|
||||||
case 0x81: idx STA CYC(6) break;
|
|
||||||
case 0x82: INV IMM NOP CYC(2) break;
|
|
||||||
case 0x83: INV NOP CYC(2) break;
|
|
||||||
case 0x84: ZPG STY CYC(3) break;
|
|
||||||
case 0x85: ZPG STA CYC(3) break;
|
|
||||||
case 0x86: ZPG STX CYC(3) break;
|
|
||||||
case 0x87: INV NOP CYC(2) break;
|
|
||||||
case 0x88: DEY CYC(2) break;
|
|
||||||
case 0x89: IMM BITI CYC(2) break;
|
|
||||||
case 0x8A: TXA CYC(2) break;
|
|
||||||
case 0x8B: INV NOP CYC(2) break;
|
|
||||||
case 0x8C: ABS STY CYC(4) break;
|
|
||||||
case 0x8D: ABS STA CYC(4) break;
|
|
||||||
case 0x8E: ABS STX CYC(4) break;
|
|
||||||
case 0x8F: INV NOP CYC(2) break;
|
|
||||||
case 0x90: REL BCC CYC(2) break;
|
|
||||||
case 0x91: idy STA CYC(6) break;
|
|
||||||
case 0x92: izp STA CYC(5) break;
|
|
||||||
case 0x93: INV NOP CYC(2) break;
|
|
||||||
case 0x94: zpx STY CYC(4) break;
|
|
||||||
case 0x95: zpx STA CYC(4) break;
|
|
||||||
case 0x96: zpy STX CYC(4) break;
|
|
||||||
case 0x97: INV NOP CYC(2) break;
|
|
||||||
case 0x98: TYA CYC(2) break;
|
|
||||||
case 0x99: aby STA CYC(5) break;
|
|
||||||
case 0x9A: TXS CYC(2) break;
|
|
||||||
case 0x9B: INV NOP CYC(2) break;
|
|
||||||
case 0x9C: ABS STZ CYC(4) break;
|
|
||||||
case 0x9D: abx STA CYC(5) break;
|
|
||||||
case 0x9E: abx STZ CYC(5) break;
|
|
||||||
case 0x9F: INV NOP CYC(2) break;
|
|
||||||
case 0xA0: IMM LDY CYC(2) break;
|
|
||||||
case 0xA1: idx LDA CYC(6) break;
|
|
||||||
case 0xA2: IMM LDX CYC(2) break;
|
|
||||||
case 0xA3: INV NOP CYC(2) break;
|
|
||||||
case 0xA4: ZPG LDY CYC(3) break;
|
|
||||||
case 0xA5: ZPG LDA CYC(3) break;
|
|
||||||
case 0xA6: ZPG LDX CYC(3) break;
|
|
||||||
case 0xA7: INV NOP CYC(2) break;
|
|
||||||
case 0xA8: TAY CYC(2) break;
|
|
||||||
case 0xA9: IMM LDA CYC(2) break;
|
|
||||||
case 0xAA: TAX CYC(2) break;
|
|
||||||
case 0xAB: INV NOP CYC(2) break;
|
|
||||||
case 0xAC: ABS LDY CYC(4) break;
|
|
||||||
case 0xAD: ABS LDA CYC(4) break;
|
|
||||||
case 0xAE: ABS LDX CYC(4) break;
|
|
||||||
case 0xAF: INV NOP CYC(2) break;
|
|
||||||
case 0xB0: REL BCS CYC(2) break;
|
|
||||||
case 0xB1: idy LDA CYC(5) break;
|
|
||||||
case 0xB2: izp LDA CYC(5) break;
|
|
||||||
case 0xB3: INV NOP CYC(2) break;
|
|
||||||
case 0xB4: zpx LDY CYC(4) break;
|
|
||||||
case 0xB5: zpx LDA CYC(4) break;
|
|
||||||
case 0xB6: zpy LDX CYC(4) break;
|
|
||||||
case 0xB7: INV NOP CYC(2) break;
|
|
||||||
case 0xB8: CLV CYC(2) break;
|
|
||||||
case 0xB9: aby LDA CYC(4) break;
|
|
||||||
case 0xBA: TSX CYC(2) break;
|
|
||||||
case 0xBB: INV NOP CYC(2) break;
|
|
||||||
case 0xBC: abx LDY CYC(4) break;
|
|
||||||
case 0xBD: abx LDA CYC(4) break;
|
|
||||||
case 0xBE: aby LDX CYC(4) break;
|
|
||||||
case 0xBF: INV NOP CYC(2) break;
|
|
||||||
case 0xC0: IMM CPY CYC(2) break;
|
|
||||||
case 0xC1: idx CMP CYC(6) break;
|
|
||||||
case 0xC2: INV IMM NOP CYC(2) break;
|
|
||||||
case 0xC3: INV NOP CYC(2) break;
|
|
||||||
case 0xC4: ZPG CPY CYC(3) break;
|
|
||||||
case 0xC5: ZPG CMP CYC(3) break;
|
|
||||||
case 0xC6: ZPG DEC_CMOS CYC(5) break;
|
|
||||||
case 0xC7: INV NOP CYC(2) break;
|
|
||||||
case 0xC8: INY CYC(2) break;
|
|
||||||
case 0xC9: IMM CMP CYC(2) break;
|
|
||||||
case 0xCA: DEX CYC(2) break;
|
|
||||||
case 0xCB: INV NOP CYC(2) break;
|
|
||||||
case 0xCC: ABS CPY CYC(4) break;
|
|
||||||
case 0xCD: ABS CMP CYC(4) break;
|
|
||||||
case 0xCE: ABS DEC_CMOS CYC(5) break;
|
|
||||||
case 0xCF: INV NOP CYC(2) break;
|
|
||||||
case 0xD0: REL BNE CYC(2) break;
|
|
||||||
case 0xD1: idy CMP CYC(5) break;
|
|
||||||
case 0xD2: izp CMP CYC(5) break;
|
|
||||||
case 0xD3: INV NOP CYC(2) break;
|
|
||||||
case 0xD4: INV zpx NOP CYC(4) break;
|
|
||||||
case 0xD5: zpx CMP CYC(4) break;
|
|
||||||
case 0xD6: zpx DEC_CMOS CYC(6) break;
|
|
||||||
case 0xD7: INV NOP CYC(2) break;
|
|
||||||
case 0xD8: CLD CYC(2) break;
|
|
||||||
case 0xD9: aby CMP CYC(4) break;
|
|
||||||
case 0xDA: PHX CYC(3) break;
|
|
||||||
case 0xDB: INV NOP CYC(2) break;
|
|
||||||
case 0xDC: INV abx NOP CYC(4) break;
|
|
||||||
case 0xDD: abx CMP CYC(4) break;
|
|
||||||
case 0xDE: abx DEC_CMOS CYC(6) break;
|
|
||||||
case 0xDF: INV NOP CYC(2) break;
|
|
||||||
case 0xE0: IMM CPX CYC(2) break;
|
|
||||||
case 0xE1: idx SBC_CMOS CYC(6) break;
|
|
||||||
case 0xE2: INV IMM NOP CYC(2) break;
|
|
||||||
case 0xE3: INV NOP CYC(2) break;
|
|
||||||
case 0xE4: ZPG CPX CYC(3) break;
|
|
||||||
case 0xE5: ZPG SBC_CMOS CYC(3) break;
|
|
||||||
case 0xE6: ZPG INC_CMOS CYC(5) break;
|
|
||||||
case 0xE7: INV NOP CYC(2) break;
|
|
||||||
case 0xE8: INX CYC(2) break;
|
|
||||||
case 0xE9: IMM SBC_CMOS CYC(2) break;
|
|
||||||
case 0xEA: NOP CYC(2) break;
|
|
||||||
case 0xEB: INV NOP CYC(2) break;
|
|
||||||
case 0xEC: ABS CPX CYC(4) break;
|
|
||||||
case 0xED: ABS SBC_CMOS CYC(4) break;
|
|
||||||
case 0xEE: ABS INC_CMOS CYC(6) break;
|
|
||||||
case 0xEF: INV NOP CYC(2) break;
|
|
||||||
case 0xF0: REL BEQ CYC(2) break;
|
|
||||||
case 0xF1: idy SBC_CMOS CYC(5) break;
|
|
||||||
case 0xF2: izp SBC_CMOS CYC(5) break;
|
|
||||||
case 0xF3: INV NOP CYC(2) break;
|
|
||||||
case 0xF4: INV zpx NOP CYC(4) break;
|
|
||||||
case 0xF5: zpx SBC_CMOS CYC(4) break;
|
|
||||||
case 0xF6: zpx INC_CMOS CYC(6) break;
|
|
||||||
case 0xF7: INV NOP CYC(2) break;
|
|
||||||
case 0xF8: SED CYC(2) break;
|
|
||||||
case 0xF9: aby SBC_CMOS CYC(4) break;
|
|
||||||
case 0xFA: PLX CYC(4) break;
|
|
||||||
case 0xFB: INV NOP CYC(2) break;
|
|
||||||
case 0xFC: INV abx NOP CYC(4) break;
|
|
||||||
case 0xFD: abx SBC_CMOS CYC(4) break;
|
|
||||||
case 0xFE: abx INC_CMOS CYC(6) break;
|
|
||||||
case 0xFF: INV NOP CYC(2) break;
|
|
||||||
*/
|
|
||||||
// Version 2 opcode: $ AM Instruction // $=DebugBreak AM=AddressingMode
|
// Version 2 opcode: $ AM Instruction // $=DebugBreak AM=AddressingMode
|
||||||
//! ! ! ! ! ! // Tab-Stops
|
//! ! ! ! ! ! // Tab-Stops
|
||||||
case 0x00: BRK CYC(7) break;
|
case 0x00: BRK CYC(7) break;
|
||||||
|
@ -411,7 +166,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x0E: ABS ASLc CYC(6) break;
|
case 0x0E: ABS ASLc CYC(6) break;
|
||||||
case 0x0F: $ NOP CYC(2) break;
|
case 0x0F: $ NOP CYC(2) break;
|
||||||
case 0x10: REL BPL CYC(2) break;
|
case 0x10: REL BPL CYC(2) break;
|
||||||
case 0x11: idy ORA CYC(5) break;
|
case 0x11: INDY_OPT ORA CYC(5) break;
|
||||||
case 0x12: izp ORA CYC(5) break;
|
case 0x12: izp ORA CYC(5) break;
|
||||||
case 0x13: $ NOP CYC(2) break;
|
case 0x13: $ NOP CYC(2) break;
|
||||||
case 0x14: ZPG TRB CYC(5) break;
|
case 0x14: ZPG TRB CYC(5) break;
|
||||||
|
@ -419,12 +174,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x16: zpx ASLc CYC(6) break;
|
case 0x16: zpx ASLc CYC(6) break;
|
||||||
case 0x17: $ NOP CYC(2) break;
|
case 0x17: $ NOP CYC(2) break;
|
||||||
case 0x18: CLC CYC(2) break;
|
case 0x18: CLC CYC(2) break;
|
||||||
case 0x19: aby ORA CYC(4) break;
|
case 0x19: ABSY_OPT ORA CYC(4) break;
|
||||||
case 0x1A: INA CYC(2) break;
|
case 0x1A: INA CYC(2) break;
|
||||||
case 0x1B: $ NOP CYC(2) break;
|
case 0x1B: $ NOP CYC(2) break;
|
||||||
case 0x1C: ABS TRB CYC(6) break;
|
case 0x1C: ABS TRB CYC(6) break;
|
||||||
case 0x1D: abx ORA CYC(4) break;
|
case 0x1D: ABSX_OPT ORA CYC(4) break;
|
||||||
case 0x1E: abx ASLc CYC(6) break;
|
case 0x1E: ABSX_OPT ASLc CYC(6) break;
|
||||||
case 0x1F: $ NOP CYC(2) break;
|
case 0x1F: $ NOP CYC(2) break;
|
||||||
case 0x20: ABS JSR CYC(6) break;
|
case 0x20: ABS JSR CYC(6) break;
|
||||||
case 0x21: idx AND CYC(6) break;
|
case 0x21: idx AND CYC(6) break;
|
||||||
|
@ -443,7 +198,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x2E: ABS ROLc CYC(6) break;
|
case 0x2E: ABS ROLc CYC(6) break;
|
||||||
case 0x2F: $ NOP CYC(2) break;
|
case 0x2F: $ NOP CYC(2) break;
|
||||||
case 0x30: REL BMI CYC(2) break;
|
case 0x30: REL BMI CYC(2) break;
|
||||||
case 0x31: idy AND CYC(5) break;
|
case 0x31: INDY_OPT AND CYC(5) break;
|
||||||
case 0x32: izp AND CYC(5) break;
|
case 0x32: izp AND CYC(5) break;
|
||||||
case 0x33: $ NOP CYC(2) break;
|
case 0x33: $ NOP CYC(2) break;
|
||||||
case 0x34: zpx BIT CYC(4) break;
|
case 0x34: zpx BIT CYC(4) break;
|
||||||
|
@ -451,12 +206,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x36: zpx ROLc CYC(6) break;
|
case 0x36: zpx ROLc CYC(6) break;
|
||||||
case 0x37: $ NOP CYC(2) break;
|
case 0x37: $ NOP CYC(2) break;
|
||||||
case 0x38: SEC CYC(2) break;
|
case 0x38: SEC CYC(2) break;
|
||||||
case 0x39: aby AND CYC(4) break;
|
case 0x39: ABSY_OPT AND CYC(4) break;
|
||||||
case 0x3A: DEA CYC(2) break;
|
case 0x3A: DEA CYC(2) break;
|
||||||
case 0x3B: $ NOP CYC(2) break;
|
case 0x3B: $ NOP CYC(2) break;
|
||||||
case 0x3C: abx BIT CYC(4) break;
|
case 0x3C: ABSX_OPT BIT CYC(4) break;
|
||||||
case 0x3D: abx AND CYC(4) break;
|
case 0x3D: ABSX_OPT AND CYC(4) break;
|
||||||
case 0x3E: abx ROLc CYC(6) break;
|
case 0x3E: ABSX_OPT ROLc CYC(6) break;
|
||||||
case 0x3F: $ NOP CYC(2) break;
|
case 0x3F: $ NOP CYC(2) break;
|
||||||
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
|
case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break;
|
||||||
case 0x41: idx EOR CYC(6) break;
|
case 0x41: idx EOR CYC(6) break;
|
||||||
|
@ -475,7 +230,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x4E: ABS LSRc CYC(6) break;
|
case 0x4E: ABS LSRc CYC(6) break;
|
||||||
case 0x4F: $ NOP CYC(2) break;
|
case 0x4F: $ NOP CYC(2) break;
|
||||||
case 0x50: REL BVC CYC(2) break;
|
case 0x50: REL BVC CYC(2) break;
|
||||||
case 0x51: idy EOR CYC(5) break;
|
case 0x51: INDY_OPT EOR CYC(5) break;
|
||||||
case 0x52: izp EOR CYC(5) break;
|
case 0x52: izp EOR CYC(5) break;
|
||||||
case 0x53: $ NOP CYC(2) break;
|
case 0x53: $ NOP CYC(2) break;
|
||||||
case 0x54: $ zpx NOP CYC(4) break;
|
case 0x54: $ zpx NOP CYC(4) break;
|
||||||
|
@ -483,12 +238,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x56: zpx LSRc CYC(6) break;
|
case 0x56: zpx LSRc CYC(6) break;
|
||||||
case 0x57: $ NOP CYC(2) break;
|
case 0x57: $ NOP CYC(2) break;
|
||||||
case 0x58: CLI CYC(2) break;
|
case 0x58: CLI CYC(2) break;
|
||||||
case 0x59: aby EOR CYC(4) break;
|
case 0x59: ABSY_OPT EOR CYC(4) break;
|
||||||
case 0x5A: PHY CYC(3) break;
|
case 0x5A: PHY CYC(3) break;
|
||||||
case 0x5B: $ NOP CYC(2) break;
|
case 0x5B: $ NOP CYC(2) break;
|
||||||
case 0x5C: $ abx NOP CYC(8) break;
|
case 0x5C: $ ABSX_OPT NOP CYC(8) break;
|
||||||
case 0x5D: abx EOR CYC(4) break;
|
case 0x5D: ABSX_OPT EOR CYC(4) break;
|
||||||
case 0x5E: abx LSRc CYC(6) break;
|
case 0x5E: ABSX_OPT LSRc CYC(6) break;
|
||||||
case 0x5F: $ NOP CYC(2) break;
|
case 0x5F: $ NOP CYC(2) break;
|
||||||
case 0x60: RTS CYC(6) break;
|
case 0x60: RTS CYC(6) break;
|
||||||
case 0x61: idx ADCc CYC(6) break;
|
case 0x61: idx ADCc CYC(6) break;
|
||||||
|
@ -502,12 +257,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x69: IMM ADCc CYC(2) break;
|
case 0x69: IMM ADCc CYC(2) break;
|
||||||
case 0x6A: ror CYC(2) break;
|
case 0x6A: ror CYC(2) break;
|
||||||
case 0x6B: $ NOP CYC(2) break;
|
case 0x6B: $ NOP CYC(2) break;
|
||||||
case 0x6C: IABSCMOS JMP CYC(6) break; // 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP
|
case 0x6C: IABS_CMOS JMP CYC(6) break;
|
||||||
case 0x6D: ABS ADCc CYC(4) break;
|
case 0x6D: ABS ADCc CYC(4) break;
|
||||||
case 0x6E: ABS RORc CYC(6) break;
|
case 0x6E: ABS RORc CYC(6) break;
|
||||||
case 0x6F: $ NOP CYC(2) break;
|
case 0x6F: $ NOP CYC(2) break;
|
||||||
case 0x70: REL BVS CYC(2) break;
|
case 0x70: REL BVS CYC(2) break;
|
||||||
case 0x71: idy ADCc CYC(5) break;
|
case 0x71: INDY_OPT ADCc CYC(5) break;
|
||||||
case 0x72: izp ADCc CYC(5) break;
|
case 0x72: izp ADCc CYC(5) break;
|
||||||
case 0x73: $ NOP CYC(2) break;
|
case 0x73: $ NOP CYC(2) break;
|
||||||
case 0x74: zpx STZ CYC(4) break;
|
case 0x74: zpx STZ CYC(4) break;
|
||||||
|
@ -515,12 +270,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x76: zpx RORc CYC(6) break;
|
case 0x76: zpx RORc CYC(6) break;
|
||||||
case 0x77: $ NOP CYC(2) break;
|
case 0x77: $ NOP CYC(2) break;
|
||||||
case 0x78: SEI CYC(2) break;
|
case 0x78: SEI CYC(2) break;
|
||||||
case 0x79: aby ADCc CYC(4) break;
|
case 0x79: ABSY_OPT ADCc CYC(4) break;
|
||||||
case 0x7A: PLY CYC(4) break;
|
case 0x7A: PLY CYC(4) break;
|
||||||
case 0x7B: $ NOP CYC(2) break;
|
case 0x7B: $ NOP CYC(2) break;
|
||||||
case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP
|
case 0x7C: IABSX JMP CYC(6) break;
|
||||||
case 0x7D: abx ADCc CYC(4) break;
|
case 0x7D: ABSX_OPT ADCc CYC(4) break;
|
||||||
case 0x7E: abx RORc CYC(6) break;
|
case 0x7E: ABSX_OPT RORc CYC(6) break;
|
||||||
case 0x7F: $ NOP CYC(2) break;
|
case 0x7F: $ NOP CYC(2) break;
|
||||||
case 0x80: REL BRA CYC(2) break;
|
case 0x80: REL BRA CYC(2) break;
|
||||||
case 0x81: idx STA CYC(6) break;
|
case 0x81: idx STA CYC(6) break;
|
||||||
|
@ -539,7 +294,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x8E: ABS STX CYC(4) break;
|
case 0x8E: ABS STX CYC(4) break;
|
||||||
case 0x8F: $ NOP CYC(2) break;
|
case 0x8F: $ NOP CYC(2) break;
|
||||||
case 0x90: REL BCC CYC(2) break;
|
case 0x90: REL BCC CYC(2) break;
|
||||||
case 0x91: idy STA CYC(6) break;
|
case 0x91: INDY_CONST STA CYC(6) break;
|
||||||
case 0x92: izp STA CYC(5) break;
|
case 0x92: izp STA CYC(5) break;
|
||||||
case 0x93: $ NOP CYC(2) break;
|
case 0x93: $ NOP CYC(2) break;
|
||||||
case 0x94: zpx STY CYC(4) break;
|
case 0x94: zpx STY CYC(4) break;
|
||||||
|
@ -547,12 +302,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0x96: zpy STX CYC(4) break;
|
case 0x96: zpy STX CYC(4) break;
|
||||||
case 0x97: $ NOP CYC(2) break;
|
case 0x97: $ NOP CYC(2) break;
|
||||||
case 0x98: TYA CYC(2) break;
|
case 0x98: TYA CYC(2) break;
|
||||||
case 0x99: aby STA CYC(5) break;
|
case 0x99: ABSY_CONST STA CYC(5) break;
|
||||||
case 0x9A: TXS CYC(2) break;
|
case 0x9A: TXS CYC(2) break;
|
||||||
case 0x9B: $ NOP CYC(2) break;
|
case 0x9B: $ NOP CYC(2) break;
|
||||||
case 0x9C: ABS STZ CYC(4) break;
|
case 0x9C: ABS STZ CYC(4) break;
|
||||||
case 0x9D: abx STA CYC(5) break;
|
case 0x9D: ABSX_CONST STA CYC(5) break;
|
||||||
case 0x9E: abx STZ CYC(5) break;
|
case 0x9E: ABSX_CONST STZ CYC(5) break;
|
||||||
case 0x9F: $ NOP CYC(2) break;
|
case 0x9F: $ NOP CYC(2) break;
|
||||||
case 0xA0: IMM LDY CYC(2) break;
|
case 0xA0: IMM LDY CYC(2) break;
|
||||||
case 0xA1: idx LDA CYC(6) break;
|
case 0xA1: idx LDA CYC(6) break;
|
||||||
|
@ -571,7 +326,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0xAE: ABS LDX CYC(4) break;
|
case 0xAE: ABS LDX CYC(4) break;
|
||||||
case 0xAF: $ NOP CYC(2) break;
|
case 0xAF: $ NOP CYC(2) break;
|
||||||
case 0xB0: REL BCS CYC(2) break;
|
case 0xB0: REL BCS CYC(2) break;
|
||||||
case 0xB1: idy LDA CYC(5) break;
|
case 0xB1: INDY_OPT LDA CYC(5) break;
|
||||||
case 0xB2: izp LDA CYC(5) break;
|
case 0xB2: izp LDA CYC(5) break;
|
||||||
case 0xB3: $ NOP CYC(2) break;
|
case 0xB3: $ NOP CYC(2) break;
|
||||||
case 0xB4: zpx LDY CYC(4) break;
|
case 0xB4: zpx LDY CYC(4) break;
|
||||||
|
@ -579,12 +334,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0xB6: zpy LDX CYC(4) break;
|
case 0xB6: zpy LDX CYC(4) break;
|
||||||
case 0xB7: $ NOP CYC(2) break;
|
case 0xB7: $ NOP CYC(2) break;
|
||||||
case 0xB8: CLV CYC(2) break;
|
case 0xB8: CLV CYC(2) break;
|
||||||
case 0xB9: aby LDA CYC(4) break;
|
case 0xB9: ABSY_OPT LDA CYC(4) break;
|
||||||
case 0xBA: TSX CYC(2) break;
|
case 0xBA: TSX CYC(2) break;
|
||||||
case 0xBB: $ NOP CYC(2) break;
|
case 0xBB: $ NOP CYC(2) break;
|
||||||
case 0xBC: abx LDY CYC(4) break;
|
case 0xBC: ABSX_OPT LDY CYC(4) break;
|
||||||
case 0xBD: abx LDA CYC(4) break;
|
case 0xBD: ABSX_OPT LDA CYC(4) break;
|
||||||
case 0xBE: aby LDX CYC(4) break;
|
case 0xBE: ABSY_OPT LDX CYC(4) break;
|
||||||
case 0xBF: $ NOP CYC(2) break;
|
case 0xBF: $ NOP CYC(2) break;
|
||||||
case 0xC0: IMM CPY CYC(2) break;
|
case 0xC0: IMM CPY CYC(2) break;
|
||||||
case 0xC1: idx CMP CYC(6) break;
|
case 0xC1: idx CMP CYC(6) break;
|
||||||
|
@ -592,7 +347,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0xC3: $ NOP CYC(2) break;
|
case 0xC3: $ NOP CYC(2) break;
|
||||||
case 0xC4: ZPG CPY CYC(3) break;
|
case 0xC4: ZPG CPY CYC(3) break;
|
||||||
case 0xC5: ZPG CMP CYC(3) break;
|
case 0xC5: ZPG CMP CYC(3) break;
|
||||||
case 0xC6: ZPG DECc CYC(5) break;
|
case 0xC6: ZPG DEC CYC(5) break;
|
||||||
case 0xC7: $ NOP CYC(2) break;
|
case 0xC7: $ NOP CYC(2) break;
|
||||||
case 0xC8: INY CYC(2) break;
|
case 0xC8: INY CYC(2) break;
|
||||||
case 0xC9: IMM CMP CYC(2) break;
|
case 0xC9: IMM CMP CYC(2) break;
|
||||||
|
@ -600,23 +355,23 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0xCB: $ NOP CYC(2) break;
|
case 0xCB: $ NOP CYC(2) break;
|
||||||
case 0xCC: ABS CPY CYC(4) break;
|
case 0xCC: ABS CPY CYC(4) break;
|
||||||
case 0xCD: ABS CMP CYC(4) break;
|
case 0xCD: ABS CMP CYC(4) break;
|
||||||
case 0xCE: ABS DECc CYC(5) break;
|
case 0xCE: ABS DEC CYC(6) break;
|
||||||
case 0xCF: $ NOP CYC(2) break;
|
case 0xCF: $ NOP CYC(2) break;
|
||||||
case 0xD0: REL BNE CYC(2) break;
|
case 0xD0: REL BNE CYC(2) break;
|
||||||
case 0xD1: idy CMP CYC(5) break;
|
case 0xD1: INDY_OPT CMP CYC(5) break;
|
||||||
case 0xD2: izp CMP CYC(5) break;
|
case 0xD2: izp CMP CYC(5) break;
|
||||||
case 0xD3: $ NOP CYC(2) break;
|
case 0xD3: $ NOP CYC(2) break;
|
||||||
case 0xD4: $ zpx NOP CYC(4) break;
|
case 0xD4: $ zpx NOP CYC(4) break;
|
||||||
case 0xD5: zpx CMP CYC(4) break;
|
case 0xD5: zpx CMP CYC(4) break;
|
||||||
case 0xD6: zpx DECc CYC(6) break;
|
case 0xD6: zpx DEC CYC(6) break;
|
||||||
case 0xD7: $ NOP CYC(2) break;
|
case 0xD7: $ NOP CYC(2) break;
|
||||||
case 0xD8: CLD CYC(2) break;
|
case 0xD8: CLD CYC(2) break;
|
||||||
case 0xD9: aby CMP CYC(4) break;
|
case 0xD9: ABSY_OPT CMP CYC(4) break;
|
||||||
case 0xDA: PHX CYC(3) break;
|
case 0xDA: PHX CYC(3) break;
|
||||||
case 0xDB: $ NOP CYC(2) break;
|
case 0xDB: $ NOP CYC(2) break;
|
||||||
case 0xDC: $ abx NOP CYC(4) break;
|
case 0xDC: $ ABSX_OPT NOP CYC(4) break;
|
||||||
case 0xDD: abx CMP CYC(4) break;
|
case 0xDD: ABSX_OPT CMP CYC(4) break;
|
||||||
case 0xDE: abx DECc CYC(6) break;
|
case 0xDE: ABSX_CONST DEC CYC(7) break;
|
||||||
case 0xDF: $ NOP CYC(2) break;
|
case 0xDF: $ NOP CYC(2) break;
|
||||||
case 0xE0: IMM CPX CYC(2) break;
|
case 0xE0: IMM CPX CYC(2) break;
|
||||||
case 0xE1: idx SBCc CYC(6) break;
|
case 0xE1: idx SBCc CYC(6) break;
|
||||||
|
@ -624,7 +379,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0xE3: $ NOP CYC(2) break;
|
case 0xE3: $ NOP CYC(2) break;
|
||||||
case 0xE4: ZPG CPX CYC(3) break;
|
case 0xE4: ZPG CPX CYC(3) break;
|
||||||
case 0xE5: ZPG SBCc CYC(3) break;
|
case 0xE5: ZPG SBCc CYC(3) break;
|
||||||
case 0xE6: ZPG INCc CYC(5) break;
|
case 0xE6: ZPG INC CYC(5) break;
|
||||||
case 0xE7: $ NOP CYC(2) break;
|
case 0xE7: $ NOP CYC(2) break;
|
||||||
case 0xE8: INX CYC(2) break;
|
case 0xE8: INX CYC(2) break;
|
||||||
case 0xE9: IMM SBCc CYC(2) break;
|
case 0xE9: IMM SBCc CYC(2) break;
|
||||||
|
@ -632,23 +387,23 @@ static DWORD Cpu65D02 (DWORD uTotalCycles)
|
||||||
case 0xEB: $ NOP CYC(2) break;
|
case 0xEB: $ NOP CYC(2) break;
|
||||||
case 0xEC: ABS CPX CYC(4) break;
|
case 0xEC: ABS CPX CYC(4) break;
|
||||||
case 0xED: ABS SBCc CYC(4) break;
|
case 0xED: ABS SBCc CYC(4) break;
|
||||||
case 0xEE: ABS INCc CYC(6) break;
|
case 0xEE: ABS INC CYC(6) break;
|
||||||
case 0xEF: $ NOP CYC(2) break;
|
case 0xEF: $ NOP CYC(2) break;
|
||||||
case 0xF0: REL BEQ CYC(2) break;
|
case 0xF0: REL BEQ CYC(2) break;
|
||||||
case 0xF1: idy SBCc CYC(5) break;
|
case 0xF1: INDY_OPT SBCc CYC(5) break;
|
||||||
case 0xF2: izp SBCc CYC(5) break;
|
case 0xF2: izp SBCc CYC(5) break;
|
||||||
case 0xF3: $ NOP CYC(2) break;
|
case 0xF3: $ NOP CYC(2) break;
|
||||||
case 0xF4: $ zpx NOP CYC(4) break;
|
case 0xF4: $ zpx NOP CYC(4) break;
|
||||||
case 0xF5: zpx SBCc CYC(4) break;
|
case 0xF5: zpx SBCc CYC(4) break;
|
||||||
case 0xF6: zpx INCc CYC(6) break;
|
case 0xF6: zpx INC CYC(6) break;
|
||||||
case 0xF7: $ NOP CYC(2) break;
|
case 0xF7: $ NOP CYC(2) break;
|
||||||
case 0xF8: SED CYC(2) break;
|
case 0xF8: SED CYC(2) break;
|
||||||
case 0xF9: aby SBCc CYC(4) break;
|
case 0xF9: ABSY_OPT SBCc CYC(4) break;
|
||||||
case 0xFA: PLX CYC(4) break;
|
case 0xFA: PLX CYC(4) break;
|
||||||
case 0xFB: $ NOP CYC(2) break;
|
case 0xFB: $ NOP CYC(2) break;
|
||||||
case 0xFC: $ abx NOP CYC(4) break;
|
case 0xFC: $ ABSX_OPT NOP CYC(4) break;
|
||||||
case 0xFD: abx SBCc CYC(4) break;
|
case 0xFD: ABSX_OPT SBCc CYC(4) break;
|
||||||
case 0xFE: abx INCc CYC(6) break;
|
case 0xFE: ABSX_CONST INC CYC(7) break;
|
||||||
case 0xFF: $ NOP CYC(2) break;
|
case 0xFF: $ NOP CYC(2) break;
|
||||||
}
|
}
|
||||||
#undef $
|
#undef $
|
||||||
|
|
|
@ -73,6 +73,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
IOWrite[(addr>>4) & 0xFF](regs.pc,addr,1,(BYTE)(a),uExecutedCycles); \
|
IOWrite[(addr>>4) & 0xFF](regs.pc,addr,1,(BYTE)(a),uExecutedCycles); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ON_PAGECROSS_REPLACE_HI_ADDR if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
// ExtraCycles:
|
// ExtraCycles:
|
||||||
|
@ -89,10 +91,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#define CHECK_PAGE_CHANGE if (bSlowerOnPagecross) { \
|
// TODO Optimization Note: uExtraCycles = ((base ^ addr) >> 8) & 1;
|
||||||
if ((base ^ addr) & 0xFF00) \
|
#define CHECK_PAGE_CHANGE if ((base ^ addr) & 0xFF00) \
|
||||||
uExtraCycles=1; \
|
uExtraCycles=1;
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
|
@ -102,37 +103,59 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
#define ABS addr = *(LPWORD)(mem+regs.pc); regs.pc += 2;
|
#define ABS addr = *(LPWORD)(mem+regs.pc); regs.pc += 2;
|
||||||
#define IABSX addr = *(LPWORD)(mem+(*(LPWORD)(mem+regs.pc))+(WORD)regs.x); regs.pc += 2;
|
#define IABSX addr = *(LPWORD)(mem+(*(LPWORD)(mem+regs.pc))+(WORD)regs.x); regs.pc += 2;
|
||||||
#define ABSX base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE;
|
|
||||||
#define ABSY base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE;
|
// Optimised for page-cross
|
||||||
// TODO Optimization Note: uExtraCycles = ((base & 0xFF) + 1) >> 8;
|
#define ABSX_OPT base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE;
|
||||||
#define IABSCMOS base = *(LPWORD)(mem+regs.pc); \
|
// Not optimised for page-cross
|
||||||
|
#define ABSX_CONST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2;
|
||||||
|
|
||||||
|
// Optimised for page-cross
|
||||||
|
#define ABSY_OPT base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE;
|
||||||
|
// Not optimised for page-cross
|
||||||
|
#define ABSY_CONST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2;
|
||||||
|
|
||||||
|
// TODO Optimization Note (just for IABSCMOS): uExtraCycles = ((base & 0xFF) + 1) >> 8;
|
||||||
|
#define IABS_CMOS base = *(LPWORD)(mem+regs.pc); \
|
||||||
addr = *(LPWORD)(mem+base); \
|
addr = *(LPWORD)(mem+base); \
|
||||||
if ((base & 0xFF) == 0xFF) uExtraCycles=1; \
|
if ((base & 0xFF) == 0xFF) uExtraCycles=1; \
|
||||||
regs.pc += 2;
|
regs.pc += 2;
|
||||||
#define IABSNMOS base = *(LPWORD)(mem+regs.pc); \
|
#define IABS_NMOS base = *(LPWORD)(mem+regs.pc); \
|
||||||
if ((base & 0xFF) == 0xFF) \
|
if ((base & 0xFF) == 0xFF) \
|
||||||
addr = *(mem+base)+((WORD)*(mem+(base&0xFF00))<<8);\
|
addr = *(mem+base)+((WORD)*(mem+(base&0xFF00))<<8);\
|
||||||
else \
|
else \
|
||||||
addr = *(LPWORD)(mem+base); \
|
addr = *(LPWORD)(mem+base); \
|
||||||
regs.pc += 2;
|
regs.pc += 2;
|
||||||
|
|
||||||
#define IMM addr = regs.pc++;
|
#define IMM addr = regs.pc++;
|
||||||
|
|
||||||
#define INDX base = ((*(mem+regs.pc++))+regs.x) & 0xFF; \
|
#define INDX base = ((*(mem+regs.pc++))+regs.x) & 0xFF; \
|
||||||
if (base == 0xFF) \
|
if (base == 0xFF) \
|
||||||
addr = *(mem+0xFF)+(((WORD)*mem)<<8); \
|
addr = *(mem+0xFF)+(((WORD)*mem)<<8); \
|
||||||
else \
|
else \
|
||||||
addr = *(LPWORD)(mem+base);
|
addr = *(LPWORD)(mem+base);
|
||||||
#define INDY if (*(mem+regs.pc) == 0xFF) \
|
|
||||||
|
// Optimised for page-cross
|
||||||
|
#define INDY_OPT if (*(mem+regs.pc) == 0xFF) /*incurs an extra cycle for page-crossing*/ \
|
||||||
base = *(mem+0xFF)+(((WORD)*mem)<<8); \
|
base = *(mem+0xFF)+(((WORD)*mem)<<8); \
|
||||||
else \
|
else \
|
||||||
base = *(LPWORD)(mem+*(mem+regs.pc)); \
|
base = *(LPWORD)(mem+*(mem+regs.pc)); \
|
||||||
regs.pc++; \
|
regs.pc++; \
|
||||||
addr = base+(WORD)regs.y; \
|
addr = base+(WORD)regs.y; \
|
||||||
CHECK_PAGE_CHANGE;
|
CHECK_PAGE_CHANGE;
|
||||||
|
// Not optimised for page-cross
|
||||||
|
#define INDY_CONST if (*(mem+regs.pc) == 0xFF) /*no extra cycle for page-crossing*/ \
|
||||||
|
base = *(mem+0xFF)+(((WORD)*mem)<<8); \
|
||||||
|
else \
|
||||||
|
base = *(LPWORD)(mem+*(mem+regs.pc)); \
|
||||||
|
regs.pc++; \
|
||||||
|
addr = base+(WORD)regs.y;
|
||||||
|
|
||||||
#define IZPG base = *(mem+regs.pc++); \
|
#define IZPG base = *(mem+regs.pc++); \
|
||||||
if (base == 0xFF) \
|
if (base == 0xFF) \
|
||||||
addr = *(mem+0xFF)+(((WORD)*mem)<<8); \
|
addr = *(mem+0xFF)+(((WORD)*mem)<<8); \
|
||||||
else \
|
else \
|
||||||
addr = *(LPWORD)(mem+base);
|
addr = *(LPWORD)(mem+base);
|
||||||
|
|
||||||
#define REL addr = (signed char)*(mem+regs.pc++);
|
#define REL addr = (signed char)*(mem+regs.pc++);
|
||||||
|
|
||||||
// TODO Optimization Note:
|
// TODO Optimization Note:
|
||||||
|
@ -143,12 +166,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#define ZPGY addr = ((*(mem+regs.pc++))+regs.y) & 0xFF;
|
#define ZPGY addr = ((*(mem+regs.pc++))+regs.y) & 0xFF;
|
||||||
|
|
||||||
// Tidy 3 char addressing modes to keep the opcode table visually aligned, clean, and readable.
|
// Tidy 3 char addressing modes to keep the opcode table visually aligned, clean, and readable.
|
||||||
#undef abx
|
|
||||||
#undef abx
|
|
||||||
#undef aby
|
|
||||||
#undef asl
|
#undef asl
|
||||||
#undef idx
|
#undef idx
|
||||||
#undef idy
|
|
||||||
#undef imm
|
#undef imm
|
||||||
#undef izp
|
#undef izp
|
||||||
#undef lsr
|
#undef lsr
|
||||||
|
@ -158,11 +177,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#undef zpx
|
#undef zpx
|
||||||
#undef zpy
|
#undef zpy
|
||||||
|
|
||||||
#define abx ABSX
|
|
||||||
#define aby ABSY
|
|
||||||
#define asl ASLA // Arithmetic Shift Left
|
#define asl ASLA // Arithmetic Shift Left
|
||||||
#define idx INDX
|
#define idx INDX
|
||||||
#define idy INDY
|
|
||||||
#define imm IMM
|
#define imm IMM
|
||||||
#define izp IZPG
|
#define izp IZPG
|
||||||
#define lsr LSRA // Logical Shift Right
|
#define lsr LSRA // Logical Shift Right
|
||||||
|
@ -171,6 +187,3 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#define ror RORA // Rotate Right
|
#define ror RORA // Rotate Right
|
||||||
#define zpx ZPGX
|
#define zpx ZPGX
|
||||||
#define zpy ZPGY
|
#define zpy ZPGY
|
||||||
// 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP
|
|
||||||
// 0x7C IABSX
|
|
||||||
|
|
||||||
|
|
|
@ -68,15 +68,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#undef CPY
|
#undef CPY
|
||||||
#undef DCM
|
#undef DCM
|
||||||
#undef DEA
|
#undef DEA
|
||||||
#undef DEC_NMOS
|
#undef DEC
|
||||||
#undef DEC_CMOS
|
|
||||||
#undef DEX
|
#undef DEX
|
||||||
#undef DEY
|
#undef DEY
|
||||||
#undef EOR
|
#undef EOR
|
||||||
#undef HLT
|
#undef HLT
|
||||||
#undef INA
|
#undef INA
|
||||||
#undef INC_NMOS
|
#undef INC
|
||||||
#undef INC_CMOS
|
|
||||||
#undef INS
|
#undef INS
|
||||||
#undef INX
|
#undef INX
|
||||||
#undef INY
|
#undef INY
|
||||||
|
@ -139,8 +137,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
#undef ADCn
|
#undef ADCn
|
||||||
#undef ASLn
|
#undef ASLn
|
||||||
#undef DECn
|
|
||||||
#undef INCn
|
|
||||||
#undef LSRn
|
#undef LSRn
|
||||||
#undef ROLn
|
#undef ROLn
|
||||||
#undef RORn
|
#undef RORn
|
||||||
|
@ -148,8 +144,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
#define ADCn ADC_NMOS
|
#define ADCn ADC_NMOS
|
||||||
#define ASLn ASL_NMOS
|
#define ASLn ASL_NMOS
|
||||||
#define DECn DEC_NMOS
|
|
||||||
#define INCn INC_NMOS
|
|
||||||
#define LSRn LSR_NMOS
|
#define LSRn LSR_NMOS
|
||||||
#define ROLn ROL_NMOS
|
#define ROLn ROL_NMOS
|
||||||
#define RORn ROR_NMOS
|
#define RORn ROR_NMOS
|
||||||
|
@ -159,8 +153,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
#undef ADCc
|
#undef ADCc
|
||||||
#undef ASLc
|
#undef ASLc
|
||||||
#undef DECc
|
|
||||||
#undef INCc
|
|
||||||
#undef LSRc
|
#undef LSRc
|
||||||
#undef ROLc
|
#undef ROLc
|
||||||
#undef RORc
|
#undef RORc
|
||||||
|
@ -168,8 +160,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
#define ADCc ADC_CMOS
|
#define ADCc ADC_CMOS
|
||||||
#define ASLc ASL_CMOS
|
#define ASLc ASL_CMOS
|
||||||
#define DECc DEC_CMOS
|
|
||||||
#define INCc INC_CMOS
|
|
||||||
#define LSRc LSR_CMOS
|
#define LSRc LSR_CMOS
|
||||||
#define ROLc ROL_CMOS
|
#define ROLc ROL_CMOS
|
||||||
#define RORc ROR_CMOS
|
#define RORc ROR_CMOS
|
||||||
|
@ -177,7 +167,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
// ==========
|
// ==========
|
||||||
|
|
||||||
#define ADC_NMOS bSlowerOnPagecross = 1; \
|
#define ADC_NMOS /*bSlowerOnPagecross = 1;*/ \
|
||||||
temp = READ; \
|
temp = READ; \
|
||||||
if (regs.ps & AF_DECIMAL) { \
|
if (regs.ps & AF_DECIMAL) { \
|
||||||
val = (regs.a & 0x0F) + (temp & 0x0F) + flagc; \
|
val = (regs.a & 0x0F) + (temp & 0x0F) + flagc; \
|
||||||
|
@ -203,7 +193,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
regs.a = val & 0xFF; \
|
regs.a = val & 0xFF; \
|
||||||
SETNZ(regs.a); \
|
SETNZ(regs.a); \
|
||||||
}
|
}
|
||||||
#define ADC_CMOS bSlowerOnPagecross = 1; \
|
#define ADC_CMOS /*bSlowerOnPagecross = 1*/; \
|
||||||
temp = READ; \
|
temp = READ; \
|
||||||
flagv = !((regs.a ^ temp) & 0x80); \
|
flagv = !((regs.a ^ temp) & 0x80); \
|
||||||
if (regs.ps & AF_DECIMAL) { \
|
if (regs.ps & AF_DECIMAL) { \
|
||||||
|
@ -242,7 +232,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
flagn = 0; \
|
flagn = 0; \
|
||||||
regs.a >>= 1; \
|
regs.a >>= 1; \
|
||||||
SETZ(regs.a)
|
SETZ(regs.a)
|
||||||
#define AND bSlowerOnPagecross = 1; \
|
#define AND /*bSlowerOnPagecross = 1;*/ \
|
||||||
regs.a &= READ; \
|
regs.a &= READ; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define ANC regs.a &= READ; \
|
#define ANC regs.a &= READ; \
|
||||||
|
@ -274,12 +264,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
flagv = ((val & 0x40) ^ ((val & 0x20) << 1)); \
|
flagv = ((val & 0x40) ^ ((val & 0x20) << 1)); \
|
||||||
regs.a = (val & 0xFF); \
|
regs.a = (val & 0xFF); \
|
||||||
}
|
}
|
||||||
#define ASL_NMOS bSlowerOnPagecross = 0; \
|
#define ASL_NMOS /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ << 1; \
|
val = READ << 1; \
|
||||||
flagc = (val > 0xFF); \
|
flagc = (val > 0xFF); \
|
||||||
SETNZ(val) \
|
SETNZ(val) \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
#define ASL_CMOS bSlowerOnPagecross = 1; \
|
#define ASL_CMOS /*bSlowerOnPagecross = 1*/; \
|
||||||
val = READ << 1; \
|
val = READ << 1; \
|
||||||
flagc = (val > 0xFF); \
|
flagc = (val > 0xFF); \
|
||||||
SETNZ(val) \
|
SETNZ(val) \
|
||||||
|
@ -288,21 +278,22 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
flagc = (val > 0xFF); \
|
flagc = (val > 0xFF); \
|
||||||
SETNZ(val) \
|
SETNZ(val) \
|
||||||
regs.a = (BYTE)val;
|
regs.a = (BYTE)val;
|
||||||
#define ASO bSlowerOnPagecross = 0; \
|
#define ASO /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ << 1; \
|
val = READ << 1; \
|
||||||
flagc = (val > 0xFF); \
|
flagc = (val > 0xFF); \
|
||||||
WRITE(val) \
|
WRITE(val) \
|
||||||
regs.a |= val; \
|
regs.a |= val; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define AXA bSlowerOnPagecross = 0;/*FIXME: $93 case is still unclear*/ \
|
#define AXA /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = regs.a & regs.x & (((base >> 8) + 1) & 0xFF); \
|
val = regs.a & regs.x & (((base >> 8) + 1) & 0xFF); \
|
||||||
|
ON_PAGECROSS_REPLACE_HI_ADDR \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
#define AXS bSlowerOnPagecross = 0; \
|
#define AXS /*bSlowerOnPagecross = 0;*/ \
|
||||||
WRITE(regs.a & regs.x)
|
WRITE(regs.a & regs.x)
|
||||||
#define BCC if (!flagc) BRANCH_TAKEN;
|
#define BCC if (!flagc) BRANCH_TAKEN;
|
||||||
#define BCS if ( flagc) BRANCH_TAKEN;
|
#define BCS if ( flagc) BRANCH_TAKEN;
|
||||||
#define BEQ if ( flagz) BRANCH_TAKEN;
|
#define BEQ if ( flagz) BRANCH_TAKEN;
|
||||||
#define BIT bSlowerOnPagecross = 1; \
|
#define BIT /*bSlowerOnPagecross = 1;*/ \
|
||||||
val = READ; \
|
val = READ; \
|
||||||
flagz = !(regs.a & val); \
|
flagz = !(regs.a & val); \
|
||||||
flagn = val & 0x80; \
|
flagn = val & 0x80; \
|
||||||
|
@ -325,7 +316,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#define CLD regs.ps &= ~AF_DECIMAL;
|
#define CLD regs.ps &= ~AF_DECIMAL;
|
||||||
#define CLI regs.ps &= ~AF_INTERRUPT;
|
#define CLI regs.ps &= ~AF_INTERRUPT;
|
||||||
#define CLV flagv = 0;
|
#define CLV flagv = 0;
|
||||||
#define CMP bSlowerOnPagecross = 1; \
|
#define CMP /*bSlowerOnPagecross = 1;*/ \
|
||||||
val = READ; \
|
val = READ; \
|
||||||
flagc = (regs.a >= val); \
|
flagc = (regs.a >= val); \
|
||||||
val = regs.a-val; \
|
val = regs.a-val; \
|
||||||
|
@ -338,7 +329,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
flagc = (regs.y >= val); \
|
flagc = (regs.y >= val); \
|
||||||
val = regs.y-val; \
|
val = regs.y-val; \
|
||||||
SETNZ(val)
|
SETNZ(val)
|
||||||
#define DCM bSlowerOnPagecross = 0; \
|
#define DCM /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ-1; \
|
val = READ-1; \
|
||||||
WRITE(val) \
|
WRITE(val) \
|
||||||
flagc = (regs.a >= val); \
|
flagc = (regs.a >= val); \
|
||||||
|
@ -346,11 +337,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
SETNZ(val)
|
SETNZ(val)
|
||||||
#define DEA --regs.a; \
|
#define DEA --regs.a; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define DEC_NMOS bSlowerOnPagecross = 0; \
|
#define DEC /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ-1; \
|
|
||||||
SETNZ(val) \
|
|
||||||
WRITE(val)
|
|
||||||
#define DEC_CMOS bSlowerOnPagecross = 1; \
|
|
||||||
val = READ-1; \
|
val = READ-1; \
|
||||||
SETNZ(val) \
|
SETNZ(val) \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
|
@ -358,22 +345,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
SETNZ(regs.x)
|
SETNZ(regs.x)
|
||||||
#define DEY --regs.y; \
|
#define DEY --regs.y; \
|
||||||
SETNZ(regs.y)
|
SETNZ(regs.y)
|
||||||
#define EOR bSlowerOnPagecross = 1; \
|
#define EOR /*bSlowerOnPagecross = 1;*/ \
|
||||||
regs.a ^= READ; \
|
regs.a ^= READ; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define HLT regs.bJammed = 1; \
|
#define HLT regs.bJammed = 1; \
|
||||||
--regs.pc;
|
--regs.pc;
|
||||||
#define INA ++regs.a; \
|
#define INA ++regs.a; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define INC_NMOS bSlowerOnPagecross = 0; \
|
#define INC /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ+1; \
|
val = READ+1; \
|
||||||
SETNZ(val) \
|
SETNZ(val) \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
#define INC_CMOS bSlowerOnPagecross = 1; \
|
#define INS /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ+1; \
|
|
||||||
SETNZ(val) \
|
|
||||||
WRITE(val)
|
|
||||||
#define INS bSlowerOnPagecross = 0; \
|
|
||||||
val = READ+1; \
|
val = READ+1; \
|
||||||
WRITE(val) \
|
WRITE(val) \
|
||||||
temp = val; \
|
temp = val; \
|
||||||
|
@ -408,38 +391,40 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
PUSH(regs.pc >> 8) \
|
PUSH(regs.pc >> 8) \
|
||||||
PUSH(regs.pc & 0xFF) \
|
PUSH(regs.pc & 0xFF) \
|
||||||
regs.pc = addr;
|
regs.pc = addr;
|
||||||
#define LAS bSlowerOnPagecross = 1; \
|
#define LAS /*bSlowerOnPagecross = 1*/; \
|
||||||
val = (BYTE)(READ & regs.sp); \
|
val = (BYTE)(READ & regs.sp); \
|
||||||
regs.a = regs.x = (BYTE) val; \
|
regs.a = regs.x = (BYTE) val; \
|
||||||
regs.sp = val | 0x100; \
|
regs.sp = val | 0x100; \
|
||||||
SETNZ(val)
|
SETNZ(val)
|
||||||
#define LAX bSlowerOnPagecross = 1; \
|
#define LAX /*bSlowerOnPagecross = 1;*/ \
|
||||||
regs.a = regs.x = READ; \
|
regs.a = regs.x = READ; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define LDA bSlowerOnPagecross = 1; \
|
#define LDA /*bSlowerOnPagecross = 1;*/ \
|
||||||
regs.a = READ; \
|
regs.a = READ; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define LDX bSlowerOnPagecross = 1; \
|
#define LDD /*Undocumented 65C02: LoaD and Discard*/ \
|
||||||
|
READ;
|
||||||
|
#define LDX /*bSlowerOnPagecross = 1;*/ \
|
||||||
regs.x = READ; \
|
regs.x = READ; \
|
||||||
SETNZ(regs.x)
|
SETNZ(regs.x)
|
||||||
#define LDY bSlowerOnPagecross = 1; \
|
#define LDY /*bSlowerOnPagecross = 1;*/ \
|
||||||
regs.y = READ; \
|
regs.y = READ; \
|
||||||
SETNZ(regs.y)
|
SETNZ(regs.y)
|
||||||
#define LSE bSlowerOnPagecross = 0; \
|
#define LSE /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ; \
|
val = READ; \
|
||||||
flagc = (val & 1); \
|
flagc = (val & 1); \
|
||||||
val >>= 1; \
|
val >>= 1; \
|
||||||
WRITE(val) \
|
WRITE(val) \
|
||||||
regs.a ^= val; \
|
regs.a ^= val; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define LSR_NMOS bSlowerOnPagecross = 0; \
|
#define LSR_NMOS /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ; \
|
val = READ; \
|
||||||
flagc = (val & 1); \
|
flagc = (val & 1); \
|
||||||
flagn = 0; \
|
flagn = 0; \
|
||||||
val >>= 1; \
|
val >>= 1; \
|
||||||
SETZ(val) \
|
SETZ(val) \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
#define LSR_CMOS bSlowerOnPagecross = 1; \
|
#define LSR_CMOS /*bSlowerOnPagecross = 1;*/ \
|
||||||
val = READ; \
|
val = READ; \
|
||||||
flagc = (val & 1); \
|
flagc = (val & 1); \
|
||||||
flagn = 0; \
|
flagn = 0; \
|
||||||
|
@ -450,12 +435,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
flagn = 0; \
|
flagn = 0; \
|
||||||
regs.a >>= 1; \
|
regs.a >>= 1; \
|
||||||
SETZ(regs.a)
|
SETZ(regs.a)
|
||||||
#define NOP bSlowerOnPagecross = 1;
|
#define NOP /*bSlowerOnPagecross = 1;*/
|
||||||
#define OAL regs.a |= 0xEE; \
|
#define OAL regs.a |= 0xEE; \
|
||||||
regs.a &= READ; \
|
regs.a &= READ; \
|
||||||
regs.x = regs.a; \
|
regs.x = regs.a; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define ORA bSlowerOnPagecross = 1; \
|
#define ORA /*bSlowerOnPagecross = 1;*/ \
|
||||||
regs.a |= READ; \
|
regs.a |= READ; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define PHA PUSH(regs.a)
|
#define PHA PUSH(regs.a)
|
||||||
|
@ -471,18 +456,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
SETNZ(regs.x)
|
SETNZ(regs.x)
|
||||||
#define PLY regs.y = POP; \
|
#define PLY regs.y = POP; \
|
||||||
SETNZ(regs.y)
|
SETNZ(regs.y)
|
||||||
#define RLA bSlowerOnPagecross = 0; \
|
#define RLA /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = (READ << 1) | flagc; \
|
val = (READ << 1) | flagc; \
|
||||||
flagc = (val > 0xFF); \
|
flagc = (val > 0xFF); \
|
||||||
WRITE(val) \
|
WRITE(val) \
|
||||||
regs.a &= val; \
|
regs.a &= val; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define ROL_NMOS bSlowerOnPagecross = 0; \
|
#define ROL_NMOS /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = (READ << 1) | flagc; \
|
val = (READ << 1) | flagc; \
|
||||||
flagc = (val > 0xFF); \
|
flagc = (val > 0xFF); \
|
||||||
SETNZ(val) \
|
SETNZ(val) \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
#define ROL_CMOS bSlowerOnPagecross = 1; \
|
#define ROL_CMOS /*bSlowerOnPagecross = 1;*/ \
|
||||||
val = (READ << 1) | flagc; \
|
val = (READ << 1) | flagc; \
|
||||||
flagc = (val > 0xFF); \
|
flagc = (val > 0xFF); \
|
||||||
SETNZ(val) \
|
SETNZ(val) \
|
||||||
|
@ -491,13 +476,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
flagc = (val > 0xFF); \
|
flagc = (val > 0xFF); \
|
||||||
regs.a = val & 0xFF; \
|
regs.a = val & 0xFF; \
|
||||||
SETNZ(regs.a);
|
SETNZ(regs.a);
|
||||||
#define ROR_NMOS bSlowerOnPagecross = 0; \
|
#define ROR_NMOS /*bSlowerOnPagecross = 0;*/ \
|
||||||
temp = READ; \
|
temp = READ; \
|
||||||
val = (temp >> 1) | (flagc ? 0x80 : 0); \
|
val = (temp >> 1) | (flagc ? 0x80 : 0); \
|
||||||
flagc = (temp & 1); \
|
flagc = (temp & 1); \
|
||||||
SETNZ(val) \
|
SETNZ(val) \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
#define ROR_CMOS bSlowerOnPagecross = 1; \
|
#define ROR_CMOS /*bSlowerOnPagecross = 1;*/ \
|
||||||
temp = READ; \
|
temp = READ; \
|
||||||
val = (temp >> 1) | (flagc ? 0x80 : 0); \
|
val = (temp >> 1) | (flagc ? 0x80 : 0); \
|
||||||
flagc = (temp & 1); \
|
flagc = (temp & 1); \
|
||||||
|
@ -507,7 +492,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
flagc = (regs.a & 1); \
|
flagc = (regs.a & 1); \
|
||||||
regs.a = val & 0xFF; \
|
regs.a = val & 0xFF; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define RRA bSlowerOnPagecross = 0; \
|
#define RRA /*bSlowerOnPagecross = 0;*/ \
|
||||||
temp = READ; \
|
temp = READ; \
|
||||||
val = (temp >> 1) | (flagc ? 0x80 : 0); \
|
val = (temp >> 1) | (flagc ? 0x80 : 0); \
|
||||||
flagc = (temp & 1); \
|
flagc = (temp & 1); \
|
||||||
|
@ -549,10 +534,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
flagc = (temp >= val); \
|
flagc = (temp >= val); \
|
||||||
regs.x = temp-val; \
|
regs.x = temp-val; \
|
||||||
SETNZ(regs.x)
|
SETNZ(regs.x)
|
||||||
#define SAY bSlowerOnPagecross = 0; \
|
#define SAY /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = regs.y & (((base >> 8) + 1) & 0xFF); \
|
val = regs.y & (((base >> 8) + 1) & 0xFF); \
|
||||||
|
ON_PAGECROSS_REPLACE_HI_ADDR \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
#define SBC_NMOS bSlowerOnPagecross = 1; \
|
#define SBC_NMOS /*bSlowerOnPagecross = 1;*/ \
|
||||||
temp = READ; \
|
temp = READ; \
|
||||||
temp2 = regs.a - temp - !flagc; \
|
temp2 = regs.a - temp - !flagc; \
|
||||||
if (regs.ps & AF_DECIMAL) { \
|
if (regs.ps & AF_DECIMAL) { \
|
||||||
|
@ -576,7 +562,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
regs.a = val & 0xFF; \
|
regs.a = val & 0xFF; \
|
||||||
SETNZ(regs.a); \
|
SETNZ(regs.a); \
|
||||||
}
|
}
|
||||||
#define SBC_CMOS bSlowerOnPagecross = 1; \
|
#define SBC_CMOS /*bSlowerOnPagecross = 1;*/ \
|
||||||
temp = READ; \
|
temp = READ; \
|
||||||
flagv = ((regs.a ^ temp) & 0x80); \
|
flagv = ((regs.a ^ temp) & 0x80); \
|
||||||
if (regs.ps & AF_DECIMAL) { \
|
if (regs.ps & AF_DECIMAL) { \
|
||||||
|
@ -622,29 +608,30 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#define SEC flagc = 1;
|
#define SEC flagc = 1;
|
||||||
#define SED regs.ps |= AF_DECIMAL;
|
#define SED regs.ps |= AF_DECIMAL;
|
||||||
#define SEI regs.ps |= AF_INTERRUPT;
|
#define SEI regs.ps |= AF_INTERRUPT;
|
||||||
#define STA bSlowerOnPagecross = 0; \
|
#define STA /*bSlowerOnPagecross = 0;*/ \
|
||||||
WRITE(regs.a)
|
WRITE(regs.a)
|
||||||
#define STX bSlowerOnPagecross = 0; \
|
#define STX /*bSlowerOnPagecross = 0;*/ \
|
||||||
WRITE(regs.x)
|
WRITE(regs.x)
|
||||||
#define STY bSlowerOnPagecross = 0; \
|
#define STY /*bSlowerOnPagecross = 0;*/ \
|
||||||
WRITE(regs.y)
|
WRITE(regs.y)
|
||||||
#define STZ bSlowerOnPagecross = 0; \
|
#define STZ /*bSlowerOnPagecross = 0;*/ \
|
||||||
WRITE(0)
|
WRITE(0)
|
||||||
#define TAS bSlowerOnPagecross = 0; \
|
#define TAS /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = regs.a & regs.x; \
|
val = regs.a & regs.x; \
|
||||||
regs.sp = 0x100 | val; \
|
regs.sp = 0x100 | val; \
|
||||||
val &= (((base >> 8) + 1) & 0xFF); \
|
val &= (((base >> 8) + 1) & 0xFF); \
|
||||||
|
ON_PAGECROSS_REPLACE_HI_ADDR \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
#define TAX regs.x = regs.a; \
|
#define TAX regs.x = regs.a; \
|
||||||
SETNZ(regs.x)
|
SETNZ(regs.x)
|
||||||
#define TAY regs.y = regs.a; \
|
#define TAY regs.y = regs.a; \
|
||||||
SETNZ(regs.y)
|
SETNZ(regs.y)
|
||||||
#define TRB bSlowerOnPagecross = 0; \
|
#define TRB /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ; \
|
val = READ; \
|
||||||
flagz = !(regs.a & val); \
|
flagz = !(regs.a & val); \
|
||||||
val &= ~regs.a; \
|
val &= ~regs.a; \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
#define TSB bSlowerOnPagecross = 0; \
|
#define TSB /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = READ; \
|
val = READ; \
|
||||||
flagz = !(regs.a & val); \
|
flagz = !(regs.a & val); \
|
||||||
val |= regs.a; \
|
val |= regs.a; \
|
||||||
|
@ -659,7 +646,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#define XAA regs.a = regs.x; \
|
#define XAA regs.a = regs.x; \
|
||||||
regs.a &= READ; \
|
regs.a &= READ; \
|
||||||
SETNZ(regs.a)
|
SETNZ(regs.a)
|
||||||
#define XAS bSlowerOnPagecross = 0; \
|
#define XAS /*bSlowerOnPagecross = 0;*/ \
|
||||||
val = regs.x & (((base >> 8) + 1) & 0xFF); \
|
val = regs.x & (((base >> 8) + 1) & 0xFF); \
|
||||||
|
ON_PAGECROSS_REPLACE_HI_ADDR \
|
||||||
WRITE(val)
|
WRITE(val)
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ enum AppMode_e
|
||||||
// Configuration
|
// Configuration
|
||||||
#define REG_CONFIG "Configuration"
|
#define REG_CONFIG "Configuration"
|
||||||
#define REGVALUE_APPLE2_TYPE "Apple2 Type"
|
#define REGVALUE_APPLE2_TYPE "Apple2 Type"
|
||||||
|
#define REGVALUE_CPU_TYPE "CPU Type"
|
||||||
#define REGVALUE_OLD_APPLE2_TYPE "Computer Emulation" // Deprecated
|
#define REGVALUE_OLD_APPLE2_TYPE "Computer Emulation" // Deprecated
|
||||||
#define REGVALUE_CONFIRM_REBOOT "Confirm Reboot" // Added at 1.24.1 PageConfig
|
#define REGVALUE_CONFIRM_REBOOT "Confirm Reboot" // Added at 1.24.1 PageConfig
|
||||||
#define REGVALUE_SPKR_VOLUME "Speaker Volume"
|
#define REGVALUE_SPKR_VOLUME "Speaker Volume"
|
||||||
|
@ -165,7 +166,7 @@ enum eIRQSRC {IS_6522=0, IS_SPEECH, IS_SSC, IS_MOUSE};
|
||||||
#define IS_APPLE2C (g_Apple2Type & APPLE2C_MASK)
|
#define IS_APPLE2C (g_Apple2Type & APPLE2C_MASK)
|
||||||
#define IS_CLONE() (g_Apple2Type & APPLECLONE_MASK)
|
#define IS_CLONE() (g_Apple2Type & APPLECLONE_MASK)
|
||||||
|
|
||||||
// NB. These get persisted to the Registry, so don't change the values for these enums!
|
// NB. These get persisted to the Registry & save-state file, so don't change the values for these enums!
|
||||||
enum eApple2Type {
|
enum eApple2Type {
|
||||||
A2TYPE_APPLE2=0,
|
A2TYPE_APPLE2=0,
|
||||||
A2TYPE_APPLE2PLUS,
|
A2TYPE_APPLE2PLUS,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "..\AppleWin.h"
|
#include "..\AppleWin.h"
|
||||||
|
#include "..\CPU.h"
|
||||||
#include "..\Disk.h" // BOOL enhancedisk
|
#include "..\Disk.h" // BOOL enhancedisk
|
||||||
#include "..\HardDisk.h" // HD_CardIsEnabled()
|
#include "..\HardDisk.h" // HD_CardIsEnabled()
|
||||||
|
|
||||||
|
@ -8,13 +9,15 @@ class CConfigNeedingRestart
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CConfigNeedingRestart(UINT bEnableTheFreezesF8Rom = false) :
|
CConfigNeedingRestart(UINT bEnableTheFreezesF8Rom = false) :
|
||||||
m_Apple2Type(g_Apple2Type),
|
m_Apple2Type( GetApple2Type() ),
|
||||||
|
m_CpuType( GetMainCpu() ),
|
||||||
m_bEnhanceDisk(enhancedisk),
|
m_bEnhanceDisk(enhancedisk),
|
||||||
m_uSaveLoadStateMsg(0)
|
m_uSaveLoadStateMsg(0)
|
||||||
{
|
{
|
||||||
m_bEnableHDD = HD_CardIsEnabled();
|
m_bEnableHDD = HD_CardIsEnabled();
|
||||||
m_bEnableTheFreezesF8Rom = bEnableTheFreezesF8Rom;
|
m_bEnableTheFreezesF8Rom = bEnableTheFreezesF8Rom;
|
||||||
memset(&m_Slot, 0, sizeof(m_Slot));
|
memset(&m_Slot, 0, sizeof(m_Slot));
|
||||||
|
m_SlotAux = CT_Empty;
|
||||||
m_Slot[4] = g_Slot4;
|
m_Slot[4] = g_Slot4;
|
||||||
m_Slot[5] = g_Slot5;
|
m_Slot[5] = g_Slot5;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +25,7 @@ public:
|
||||||
const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other)
|
const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other)
|
||||||
{
|
{
|
||||||
m_Apple2Type = other.m_Apple2Type;
|
m_Apple2Type = other.m_Apple2Type;
|
||||||
|
m_CpuType = other.m_CpuType;
|
||||||
memcpy(m_Slot, other.m_Slot, sizeof(m_Slot));
|
memcpy(m_Slot, other.m_Slot, sizeof(m_Slot));
|
||||||
m_bEnhanceDisk = other.m_bEnhanceDisk;
|
m_bEnhanceDisk = other.m_bEnhanceDisk;
|
||||||
m_bEnableHDD = other.m_bEnableHDD;
|
m_bEnableHDD = other.m_bEnableHDD;
|
||||||
|
@ -33,6 +37,7 @@ public:
|
||||||
bool operator== (const CConfigNeedingRestart& other) const
|
bool operator== (const CConfigNeedingRestart& other) const
|
||||||
{
|
{
|
||||||
return m_Apple2Type == other.m_Apple2Type &&
|
return m_Apple2Type == other.m_Apple2Type &&
|
||||||
|
m_CpuType == other.m_CpuType &&
|
||||||
memcmp(m_Slot, other.m_Slot, sizeof(m_Slot)) == 0 &&
|
memcmp(m_Slot, other.m_Slot, sizeof(m_Slot)) == 0 &&
|
||||||
m_bEnhanceDisk == other.m_bEnhanceDisk &&
|
m_bEnhanceDisk == other.m_bEnhanceDisk &&
|
||||||
m_bEnableHDD == other.m_bEnableHDD &&
|
m_bEnableHDD == other.m_bEnableHDD &&
|
||||||
|
@ -46,7 +51,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
eApple2Type m_Apple2Type;
|
eApple2Type m_Apple2Type;
|
||||||
|
eCpuType m_CpuType;
|
||||||
SS_CARDTYPE m_Slot[NUM_SLOTS]; // 0..7
|
SS_CARDTYPE m_Slot[NUM_SLOTS]; // 0..7
|
||||||
|
SS_CARDTYPE m_SlotAux;
|
||||||
BOOL m_bEnhanceDisk;
|
BOOL m_bEnhanceDisk;
|
||||||
bool m_bEnableHDD;
|
bool m_bEnableHDD;
|
||||||
UINT m_bEnableTheFreezesF8Rom;
|
UINT m_bEnableTheFreezesF8Rom;
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
class CConfigNeedingRestart;
|
||||||
|
|
||||||
__interface IPropertySheet
|
__interface IPropertySheet
|
||||||
{
|
{
|
||||||
void Init(void);
|
void Init(void);
|
||||||
DWORD GetVolumeMax(void); // TODO:TC: Move out of here
|
DWORD GetVolumeMax(void); // TODO:TC: Move out of here
|
||||||
bool SaveStateSelectImage(HWND hWindow, bool bSave); // TODO:TC: Move out of here
|
bool SaveStateSelectImage(HWND hWindow, bool bSave); // TODO:TC: Move out of here
|
||||||
|
void ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld);
|
||||||
|
|
||||||
UINT GetScrollLockToggle(void);
|
UINT GetScrollLockToggle(void);
|
||||||
void SetScrollLockToggle(UINT uValue);
|
void SetScrollLockToggle(UINT uValue);
|
||||||
|
|
|
@ -22,7 +22,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "..\Structs.h"
|
|
||||||
#include "..\Common.h"
|
#include "..\Common.h"
|
||||||
|
|
||||||
#include "..\ParallelPrinter.h"
|
#include "..\ParallelPrinter.h"
|
||||||
|
|
|
@ -129,6 +129,7 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
|
||||||
const DWORD NewComputerMenuItem = (DWORD) SendDlgItemMessage(hWnd, IDC_COMPUTER, CB_GETCURSEL, 0, 0);
|
const DWORD NewComputerMenuItem = (DWORD) SendDlgItemMessage(hWnd, IDC_COMPUTER, CB_GETCURSEL, 0, 0);
|
||||||
const eApple2Type NewApple2Type = GetApple2Type(NewComputerMenuItem);
|
const eApple2Type NewApple2Type = GetApple2Type(NewComputerMenuItem);
|
||||||
m_PropertySheetHelper.GetConfigNew().m_Apple2Type = NewApple2Type;
|
m_PropertySheetHelper.GetConfigNew().m_Apple2Type = NewApple2Type;
|
||||||
|
m_PropertySheetHelper.GetConfigNew().m_CpuType = ProbeMainCpuDefault(NewApple2Type);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "..\Structs.h"
|
#include "..\SaveState_Structs_common.h"
|
||||||
#include "..\Common.h"
|
#include "..\Common.h"
|
||||||
|
|
||||||
#include "..\Keyboard.h"
|
#include "..\Keyboard.h"
|
||||||
|
@ -214,12 +214,12 @@ void CPageInput::DlgOK(HWND hWnd)
|
||||||
|
|
||||||
if (JoySetEmulationType(hWnd, m_nJoy0ChoiceTranlationTbl[uNewJoyType0], JN_JOYSTICK0, bIsSlot4Mouse))
|
if (JoySetEmulationType(hWnd, m_nJoy0ChoiceTranlationTbl[uNewJoyType0], JN_JOYSTICK0, bIsSlot4Mouse))
|
||||||
{
|
{
|
||||||
REGSAVE(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), joytype[0]);
|
REGSAVE(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), JoyGetJoyType(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JoySetEmulationType(hWnd, m_nJoy1ChoiceTranlationTbl[uNewJoyType1], JN_JOYSTICK1, bIsSlot4Mouse))
|
if (JoySetEmulationType(hWnd, m_nJoy1ChoiceTranlationTbl[uNewJoyType1], JN_JOYSTICK1, bIsSlot4Mouse))
|
||||||
{
|
{
|
||||||
REGSAVE(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), joytype[1]);
|
REGSAVE(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), JoyGetJoyType(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
JoySetTrim((short)SendDlgItemMessage(hWnd, IDC_SPIN_XTRIM, UDM_GETPOS, 0, 0), true);
|
JoySetTrim((short)SendDlgItemMessage(hWnd, IDC_SPIN_XTRIM, UDM_GETPOS, 0, 0), true);
|
||||||
|
@ -305,7 +305,7 @@ void CPageInput::InitJoystickChoices(HWND hWnd, int nJoyNum, int nIdcValue)
|
||||||
for(UINT i=nJC_KEYBD_CURSORS; i<nJC_MAX; i++)
|
for(UINT i=nJC_KEYBD_CURSORS; i<nJC_MAX; i++)
|
||||||
{
|
{
|
||||||
if( ( (i == nJC_KEYBD_CURSORS) || (i == nJC_KEYBD_NUMPAD) ) &&
|
if( ( (i == nJC_KEYBD_CURSORS) || (i == nJC_KEYBD_NUMPAD) ) &&
|
||||||
( (joytype[nOtherJoyNum] == nJC_KEYBD_CURSORS) || (joytype[nOtherJoyNum] == nJC_KEYBD_NUMPAD) )
|
( (JoyGetJoyType(nOtherJoyNum) == nJC_KEYBD_CURSORS) || (JoyGetJoyType(nOtherJoyNum) == nJC_KEYBD_NUMPAD) )
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -314,7 +314,7 @@ void CPageInput::InitJoystickChoices(HWND hWnd, int nJoyNum, int nIdcValue)
|
||||||
if (i == nJC_MOUSE && bIsSlot4Mouse)
|
if (i == nJC_MOUSE && bIsSlot4Mouse)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(joytype[nOtherJoyNum] != i)
|
if (JoyGetJoyType(nOtherJoyNum) != i)
|
||||||
{
|
{
|
||||||
memcpy(pszMem, ppszJoyChoices[i], strlen(ppszJoyChoices[i])+1);
|
memcpy(pszMem, ppszJoyChoices[i], strlen(ppszJoyChoices[i])+1);
|
||||||
pszMem += strlen(ppszJoyChoices[i])+1;
|
pszMem += strlen(ppszJoyChoices[i])+1;
|
||||||
|
@ -324,7 +324,7 @@ void CPageInput::InitJoystickChoices(HWND hWnd, int nJoyNum, int nIdcValue)
|
||||||
|
|
||||||
*pszMem = 0x00; // Doubly null terminated
|
*pszMem = 0x00; // Doubly null terminated
|
||||||
|
|
||||||
m_PropertySheetHelper.FillComboBox(hWnd, nIdcValue, pnzJoystickChoices, joytype[nJoyNum]);
|
m_PropertySheetHelper.FillComboBox(hWnd, nIdcValue, pnzJoystickChoices, JoyGetJoyType(nJoyNum));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPageInput::InitSlotOptions(HWND hWnd)
|
void CPageInput::InitSlotOptions(HWND hWnd)
|
||||||
|
|
|
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "..\Structs.h"
|
#include "..\SaveState_Structs_common.h"
|
||||||
#include "..\Common.h"
|
#include "..\Common.h"
|
||||||
|
|
||||||
#include "..\Mockingboard.h"
|
#include "..\Mockingboard.h"
|
||||||
|
@ -93,6 +93,10 @@ BOOL CPageSound::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
|
||||||
if (NewSoundcardConfigured(hWnd, wparam, CT_Phasor))
|
if (NewSoundcardConfigured(hWnd, wparam, CT_Phasor))
|
||||||
InitOptions(hWnd); // re-init
|
InitOptions(hWnd); // re-init
|
||||||
break;
|
break;
|
||||||
|
case IDC_SAM_ENABLE:
|
||||||
|
if (NewSoundcardConfigured(hWnd, wparam, CT_SAM))
|
||||||
|
InitOptions(hWnd); // re-init
|
||||||
|
break;
|
||||||
case IDC_SOUNDCARD_DISABLE:
|
case IDC_SOUNDCARD_DISABLE:
|
||||||
if (NewSoundcardConfigured(hWnd, wparam, CT_Empty))
|
if (NewSoundcardConfigured(hWnd, wparam, CT_Empty))
|
||||||
InitOptions(hWnd); // re-init
|
InitOptions(hWnd); // re-init
|
||||||
|
@ -114,7 +118,11 @@ BOOL CPageSound::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
|
||||||
SendDlgItemMessage(hWnd,IDC_MB_VOLUME,TBM_SETTICFREQ,10,0);
|
SendDlgItemMessage(hWnd,IDC_MB_VOLUME,TBM_SETTICFREQ,10,0);
|
||||||
SendDlgItemMessage(hWnd,IDC_MB_VOLUME,TBM_SETPOS,1,MB_GetVolume());
|
SendDlgItemMessage(hWnd,IDC_MB_VOLUME,TBM_SETPOS,1,MB_GetVolume());
|
||||||
|
|
||||||
|
if (g_Slot5 == CT_SAM)
|
||||||
|
m_NewCardType = CT_SAM;
|
||||||
|
else
|
||||||
m_NewCardType = MB_GetSoundcardType(); // Reinit 1st time page is activated (fires before PSN_SETACTIVE)
|
m_NewCardType = MB_GetSoundcardType(); // Reinit 1st time page is activated (fires before PSN_SETACTIVE)
|
||||||
|
|
||||||
InitOptions(hWnd);
|
InitOptions(hWnd);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -153,6 +161,8 @@ void CPageSound::InitOptions(HWND hWnd)
|
||||||
m_nCurrentIDCheckButton = IDC_MB_ENABLE;
|
m_nCurrentIDCheckButton = IDC_MB_ENABLE;
|
||||||
else if(m_NewCardType == CT_Phasor)
|
else if(m_NewCardType == CT_Phasor)
|
||||||
m_nCurrentIDCheckButton = IDC_PHASOR_ENABLE;
|
m_nCurrentIDCheckButton = IDC_PHASOR_ENABLE;
|
||||||
|
else if(m_NewCardType == CT_SAM)
|
||||||
|
m_nCurrentIDCheckButton = IDC_SAM_ENABLE;
|
||||||
else
|
else
|
||||||
m_nCurrentIDCheckButton = IDC_SOUNDCARD_DISABLE;
|
m_nCurrentIDCheckButton = IDC_SOUNDCARD_DISABLE;
|
||||||
|
|
||||||
|
@ -168,16 +178,23 @@ void CPageSound::InitOptions(HWND hWnd)
|
||||||
|
|
||||||
// Phasor button
|
// Phasor button
|
||||||
{
|
{
|
||||||
const BOOL bEnable = bIsSlot4Empty || Slot4 == CT_MockingboardC;
|
const BOOL bEnable = bIsSlot4Empty || Slot4 == CT_MockingboardC || Slot4 == CT_Phasor;
|
||||||
EnableWindow(GetDlgItem(hWnd, IDC_PHASOR_ENABLE), bEnable); // Disable Phasor (slot 4)
|
EnableWindow(GetDlgItem(hWnd, IDC_PHASOR_ENABLE), bEnable); // Disable Phasor (slot 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mockingboard button
|
// Mockingboard button
|
||||||
{
|
{
|
||||||
const BOOL bEnable = (bIsSlot4Empty || Slot4 == CT_Phasor) && bIsSlot5Empty;
|
const BOOL bEnable = (bIsSlot4Empty || Slot4 == CT_Phasor || Slot4 == CT_MockingboardC) &&
|
||||||
|
(bIsSlot5Empty || Slot5 == CT_SAM || Slot5 == CT_MockingboardC);
|
||||||
EnableWindow(GetDlgItem(hWnd, IDC_MB_ENABLE), bEnable); // Disable Mockingboard (slot 4 & 5)
|
EnableWindow(GetDlgItem(hWnd, IDC_MB_ENABLE), bEnable); // Disable Mockingboard (slot 4 & 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAM button
|
||||||
|
{
|
||||||
|
const BOOL bEnable = bIsSlot5Empty || Slot5 == CT_MockingboardC || Slot5 == CT_SAM;
|
||||||
|
EnableWindow(GetDlgItem(hWnd, IDC_SAM_ENABLE), bEnable); // Disable SAM (slot 5)
|
||||||
|
}
|
||||||
|
|
||||||
EnableWindow(GetDlgItem(hWnd, IDC_MB_VOLUME), (m_nCurrentIDCheckButton != IDC_SOUNDCARD_DISABLE) ? TRUE : FALSE);
|
EnableWindow(GetDlgItem(hWnd, IDC_MB_VOLUME), (m_nCurrentIDCheckButton != IDC_SOUNDCARD_DISABLE) ? TRUE : FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +208,7 @@ bool CPageSound::NewSoundcardConfigured(HWND hWnd, WPARAM wparam, SS_CARDTYPE Ne
|
||||||
|
|
||||||
m_NewCardType = NewCardType;
|
m_NewCardType = NewCardType;
|
||||||
|
|
||||||
|
const SS_CARDTYPE Slot4 = m_PropertySheetHelper.GetConfigNew().m_Slot[4];
|
||||||
const SS_CARDTYPE Slot5 = m_PropertySheetHelper.GetConfigNew().m_Slot[5];
|
const SS_CARDTYPE Slot5 = m_PropertySheetHelper.GetConfigNew().m_Slot[5];
|
||||||
|
|
||||||
if (NewCardType == CT_MockingboardC)
|
if (NewCardType == CT_MockingboardC)
|
||||||
|
@ -201,13 +219,20 @@ bool CPageSound::NewSoundcardConfigured(HWND hWnd, WPARAM wparam, SS_CARDTYPE Ne
|
||||||
else if (NewCardType == CT_Phasor)
|
else if (NewCardType == CT_Phasor)
|
||||||
{
|
{
|
||||||
m_PropertySheetHelper.GetConfigNew().m_Slot[4] = CT_Phasor;
|
m_PropertySheetHelper.GetConfigNew().m_Slot[4] = CT_Phasor;
|
||||||
if (Slot5 == CT_MockingboardC)
|
if ((Slot5 == CT_MockingboardC) || (Slot5 == CT_SAM))
|
||||||
m_PropertySheetHelper.GetConfigNew().m_Slot[5] = CT_Empty;
|
m_PropertySheetHelper.GetConfigNew().m_Slot[5] = CT_Empty;
|
||||||
}
|
}
|
||||||
|
else if (NewCardType == CT_SAM)
|
||||||
|
{
|
||||||
|
if ((Slot4 == CT_MockingboardC) || (Slot4 == CT_Phasor))
|
||||||
|
m_PropertySheetHelper.GetConfigNew().m_Slot[4] = CT_Empty;
|
||||||
|
m_PropertySheetHelper.GetConfigNew().m_Slot[5] = CT_SAM;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if ((Slot4 == CT_MockingboardC) || (Slot4 == CT_Phasor))
|
||||||
m_PropertySheetHelper.GetConfigNew().m_Slot[4] = CT_Empty;
|
m_PropertySheetHelper.GetConfigNew().m_Slot[4] = CT_Empty;
|
||||||
if (Slot5 == CT_MockingboardC)
|
if ((Slot5 == CT_MockingboardC) || (Slot5 == CT_SAM))
|
||||||
m_PropertySheetHelper.GetConfigNew().m_Slot[5] = CT_Empty;
|
m_PropertySheetHelper.GetConfigNew().m_Slot[5] = CT_Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@ public:
|
||||||
virtual void Init(void);
|
virtual void Init(void);
|
||||||
virtual DWORD GetVolumeMax(void); // TODO:TC: Move out of here
|
virtual DWORD GetVolumeMax(void); // TODO:TC: Move out of here
|
||||||
virtual bool SaveStateSelectImage(HWND hWindow, bool bSave); // TODO:TC: Move out of here
|
virtual bool SaveStateSelectImage(HWND hWindow, bool bSave); // TODO:TC: Move out of here
|
||||||
|
void ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld)
|
||||||
|
{
|
||||||
|
m_PropertySheetHelper.ApplyNewConfig(ConfigNew, ConfigOld);
|
||||||
|
}
|
||||||
|
|
||||||
virtual UINT GetScrollLockToggle(void){ return m_PageInput.GetScrollLockToggle(); }
|
virtual UINT GetScrollLockToggle(void){ return m_PageInput.GetScrollLockToggle(); }
|
||||||
virtual void SetScrollLockToggle(UINT uValue){ m_PageInput.SetScrollLockToggle(uValue); }
|
virtual void SetScrollLockToggle(UINT uValue){ m_PageInput.SetScrollLockToggle(uValue); }
|
||||||
|
|
|
@ -44,7 +44,7 @@ Input
|
||||||
. Mouse WM_USER_RESTART
|
. Mouse WM_USER_RESTART
|
||||||
. CP/M WM_USER_RESTART
|
. CP/M WM_USER_RESTART
|
||||||
Sound
|
Sound
|
||||||
. MB/Phasor/None WM_USER_RESTART
|
. MB/Phasor/SAM/None WM_USER_RESTART
|
||||||
Disk
|
Disk
|
||||||
. Enhanced disk speed WM_USER_RESTART Why? (used to patch Disk][ f/w - but not anymore)
|
. Enhanced disk speed WM_USER_RESTART Why? (used to patch Disk][ f/w - but not anymore)
|
||||||
. HDD enable WM_USER_RESTART
|
. HDD enable WM_USER_RESTART
|
||||||
|
@ -102,6 +102,11 @@ void CPropertySheetHelper::SaveComputerType(eApple2Type NewApple2Type)
|
||||||
REGSAVE(TEXT(REGVALUE_APPLE2_TYPE), NewApple2Type);
|
REGSAVE(TEXT(REGVALUE_APPLE2_TYPE), NewApple2Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPropertySheetHelper::SaveCpuType(eCpuType NewCpuType)
|
||||||
|
{
|
||||||
|
REGSAVE(TEXT(REGVALUE_CPU_TYPE), NewCpuType);
|
||||||
|
}
|
||||||
|
|
||||||
void CPropertySheetHelper::SetSlot4(SS_CARDTYPE NewCardType)
|
void CPropertySheetHelper::SetSlot4(SS_CARDTYPE NewCardType)
|
||||||
{
|
{
|
||||||
g_Slot4 = NewCardType;
|
g_Slot4 = NewCardType;
|
||||||
|
@ -186,7 +191,7 @@ void CPropertySheetHelper::GetDiskBaseNameWithAWS(TCHAR* pszFilename)
|
||||||
if (pDiskName && pDiskName[0])
|
if (pDiskName && pDiskName[0])
|
||||||
{
|
{
|
||||||
strcpy(pszFilename, pDiskName);
|
strcpy(pszFilename, pDiskName);
|
||||||
strcpy(&pszFilename[strlen(pDiskName)], ".aws");
|
strcpy(&pszFilename[strlen(pDiskName)], ".aws.yaml");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,9 +235,17 @@ int CPropertySheetHelper::SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bo
|
||||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||||
ofn.hwndOwner = hWindow;
|
ofn.hwndOwner = hWindow;
|
||||||
ofn.hInstance = g_hInstance;
|
ofn.hInstance = g_hInstance;
|
||||||
ofn.lpstrFilter = TEXT("Save State files (*.aws)\0*.aws\0")
|
if (bSave)
|
||||||
|
{
|
||||||
|
ofn.lpstrFilter = TEXT("Save State files (*.aws.yaml)\0*.aws.yaml\0");
|
||||||
TEXT("All Files\0*.*\0");
|
TEXT("All Files\0*.*\0");
|
||||||
ofn.lpstrFile = szFilename;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ofn.lpstrFilter = TEXT("Save State files (*.aws,*.aws.yaml)\0*.aws;*.aws.yaml\0");
|
||||||
|
TEXT("All Files\0*.*\0");
|
||||||
|
}
|
||||||
|
ofn.lpstrFile = szFilename; // Dialog strips the last .EXT from this string (eg. file.aws.yaml is displayed as: file.aws
|
||||||
ofn.nMaxFile = MAX_PATH;
|
ofn.nMaxFile = MAX_PATH;
|
||||||
ofn.lpstrInitialDir = szDirectory;
|
ofn.lpstrInitialDir = szDirectory;
|
||||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
|
||||||
|
@ -242,18 +255,39 @@ int CPropertySheetHelper::SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bo
|
||||||
|
|
||||||
if(nRes)
|
if(nRes)
|
||||||
{
|
{
|
||||||
strcpy(m_szSSNewFilename, &szFilename[ofn.nFileOffset]);
|
|
||||||
|
|
||||||
if (bSave) // Only for saving (allow loading of any file for backwards compatibility)
|
if (bSave) // Only for saving (allow loading of any file for backwards compatibility)
|
||||||
{
|
{
|
||||||
// Append .aws if it's not there
|
// Append .aws.yaml if it's not there
|
||||||
const char szAWS_EXT[] = ".aws";
|
const char szAWS_EXT1[] = ".aws";
|
||||||
const UINT uStrLenFile = strlen(m_szSSNewFilename);
|
const char szAWS_EXT2[] = ".yaml";
|
||||||
const UINT uStrLenExt = strlen(szAWS_EXT);
|
const char szAWS_EXT3[] = ".aws.yaml";
|
||||||
if ((uStrLenFile <= uStrLenExt) || (strcmp(&m_szSSNewFilename[uStrLenFile-uStrLenExt], szAWS_EXT) != 0))
|
const UINT uStrLenFile = strlen(&szFilename[ofn.nFileOffset]);
|
||||||
strcpy(&m_szSSNewFilename[uStrLenFile], szAWS_EXT);
|
const UINT uStrLenExt1 = strlen(szAWS_EXT1);
|
||||||
|
const UINT uStrLenExt2 = strlen(szAWS_EXT2);
|
||||||
|
const UINT uStrLenExt3 = strlen(szAWS_EXT3);
|
||||||
|
if (uStrLenFile <= uStrLenExt1)
|
||||||
|
{
|
||||||
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml"
|
||||||
|
}
|
||||||
|
else if (uStrLenFile <= uStrLenExt2)
|
||||||
|
{
|
||||||
|
if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0)
|
||||||
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT3); // "file.aws" -> "file" + ".aws.yaml"
|
||||||
|
else
|
||||||
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml"
|
||||||
|
}
|
||||||
|
else if ((uStrLenFile <= uStrLenExt3) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt3], szAWS_EXT3) != 0))
|
||||||
|
{
|
||||||
|
if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0)
|
||||||
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT3); // "file.aws" -> "file" + ".aws.yaml"
|
||||||
|
else if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT2) == 0)
|
||||||
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT3); // "file.yaml" -> "file" + ".aws.yaml"
|
||||||
|
else
|
||||||
|
strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strcpy(m_szSSNewFilename, &szFilename[ofn.nFileOffset]);
|
||||||
strcpy(m_szSSNewPathname, szFilename);
|
strcpy(m_szSSNewPathname, szFilename);
|
||||||
|
|
||||||
szFilename[ofn.nFileOffset] = 0;
|
szFilename[ofn.nFileOffset] = 0;
|
||||||
|
@ -319,41 +353,52 @@ bool CPropertySheetHelper::CheckChangesForRestart(HWND hWnd)
|
||||||
return true; // OK
|
return true; // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONFIG_CHANGED(var) \
|
#define CONFIG_CHANGED_LOCAL(var) \
|
||||||
(m_ConfigOld.var != m_ConfigNew.var)
|
(ConfigOld.var != ConfigNew.var)
|
||||||
|
|
||||||
// Apply changes to Registry
|
// Apply changes to Registry
|
||||||
|
void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld)
|
||||||
|
{
|
||||||
|
if (CONFIG_CHANGED_LOCAL(m_Apple2Type))
|
||||||
|
{
|
||||||
|
SaveComputerType(ConfigNew.m_Apple2Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIG_CHANGED_LOCAL(m_CpuType))
|
||||||
|
{
|
||||||
|
SaveCpuType(ConfigNew.m_CpuType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIG_CHANGED_LOCAL(m_Slot[4]))
|
||||||
|
SetSlot4(ConfigNew.m_Slot[4]);
|
||||||
|
|
||||||
|
if (CONFIG_CHANGED_LOCAL(m_Slot[5]))
|
||||||
|
SetSlot5(ConfigNew.m_Slot[5]);
|
||||||
|
|
||||||
|
if (CONFIG_CHANGED_LOCAL(m_bEnhanceDisk))
|
||||||
|
REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), ConfigNew.m_bEnhanceDisk);
|
||||||
|
|
||||||
|
if (CONFIG_CHANGED_LOCAL(m_bEnableHDD))
|
||||||
|
{
|
||||||
|
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), ConfigNew.m_bEnableHDD ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIG_CHANGED_LOCAL(m_bEnableTheFreezesF8Rom))
|
||||||
|
{
|
||||||
|
REGSAVE(TEXT(REGVALUE_THE_FREEZES_F8_ROM), ConfigNew.m_bEnableTheFreezesF8Rom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CPropertySheetHelper::ApplyNewConfig(void)
|
void CPropertySheetHelper::ApplyNewConfig(void)
|
||||||
{
|
{
|
||||||
if (CONFIG_CHANGED(m_Apple2Type))
|
ApplyNewConfig(m_ConfigNew, m_ConfigOld);
|
||||||
{
|
|
||||||
SaveComputerType(m_ConfigNew.m_Apple2Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CONFIG_CHANGED(m_Slot[4]))
|
|
||||||
SetSlot4(m_ConfigNew.m_Slot[4]);
|
|
||||||
|
|
||||||
if (CONFIG_CHANGED(m_Slot[5]))
|
|
||||||
SetSlot5(m_ConfigNew.m_Slot[5]);
|
|
||||||
|
|
||||||
if (CONFIG_CHANGED(m_bEnhanceDisk))
|
|
||||||
REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), m_ConfigNew.m_bEnhanceDisk);
|
|
||||||
|
|
||||||
if (CONFIG_CHANGED(m_bEnableHDD))
|
|
||||||
{
|
|
||||||
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), m_ConfigNew.m_bEnableHDD ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CONFIG_CHANGED(m_bEnableTheFreezesF8Rom))
|
|
||||||
{
|
|
||||||
REGSAVE(TEXT(REGVALUE_THE_FREEZES_F8_ROM), m_ConfigNew.m_bEnableTheFreezesF8Rom);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPropertySheetHelper::SaveCurrentConfig(void)
|
void CPropertySheetHelper::SaveCurrentConfig(void)
|
||||||
{
|
{
|
||||||
// NB. clone-type is encoded in g_Apple2Type
|
// NB. clone-type is encoded in g_Apple2Type
|
||||||
m_ConfigOld.m_Apple2Type = g_Apple2Type;
|
m_ConfigOld.m_Apple2Type = GetApple2Type();
|
||||||
|
m_ConfigOld.m_CpuType = GetMainCpu();
|
||||||
m_ConfigOld.m_Slot[4] = g_Slot4;
|
m_ConfigOld.m_Slot[4] = g_Slot4;
|
||||||
m_ConfigOld.m_Slot[5] = g_Slot5;
|
m_ConfigOld.m_Slot[5] = g_Slot5;
|
||||||
m_ConfigOld.m_bEnhanceDisk = enhancedisk;
|
m_ConfigOld.m_bEnhanceDisk = enhancedisk;
|
||||||
|
@ -371,7 +416,8 @@ void CPropertySheetHelper::SaveCurrentConfig(void)
|
||||||
void CPropertySheetHelper::RestoreCurrentConfig(void)
|
void CPropertySheetHelper::RestoreCurrentConfig(void)
|
||||||
{
|
{
|
||||||
// NB. clone-type is encoded in g_Apple2Type
|
// NB. clone-type is encoded in g_Apple2Type
|
||||||
g_Apple2Type = m_ConfigOld.m_Apple2Type;
|
SetApple2Type(m_ConfigOld.m_Apple2Type);
|
||||||
|
SetMainCpu(m_ConfigOld.m_CpuType);
|
||||||
g_Slot4 = m_ConfigOld.m_Slot[4];
|
g_Slot4 = m_ConfigOld.m_Slot[4];
|
||||||
g_Slot5 = m_ConfigOld.m_Slot[5];
|
g_Slot5 = m_ConfigOld.m_Slot[5];
|
||||||
enhancedisk = m_ConfigOld.m_bEnhanceDisk;
|
enhancedisk = m_ConfigOld.m_bEnhanceDisk;
|
||||||
|
@ -411,6 +457,9 @@ bool CPropertySheetHelper::IsOkToRestart(HWND hWnd)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CONFIG_CHANGED(var) \
|
||||||
|
(m_ConfigOld.var != m_ConfigNew.var)
|
||||||
|
|
||||||
bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd)
|
bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd)
|
||||||
{
|
{
|
||||||
std::string strMsg("The emulator needs to restart as the hardware configuration has changed:\n");
|
std::string strMsg("The emulator needs to restart as the hardware configuration has changed:\n");
|
||||||
|
@ -421,6 +470,9 @@ bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd)
|
||||||
if (CONFIG_CHANGED(m_Apple2Type))
|
if (CONFIG_CHANGED(m_Apple2Type))
|
||||||
strMsgMain += ". Emulated computer has changed\n";
|
strMsgMain += ". Emulated computer has changed\n";
|
||||||
|
|
||||||
|
if (CONFIG_CHANGED(m_CpuType))
|
||||||
|
strMsgMain += ". Emulated main CPU has changed\n";
|
||||||
|
|
||||||
if (CONFIG_CHANGED(m_Slot[4]))
|
if (CONFIG_CHANGED(m_Slot[4]))
|
||||||
strMsgMain += GetSlot(4);
|
strMsgMain += GetSlot(4);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ public:
|
||||||
void SetSlot5(SS_CARDTYPE NewCardType);
|
void SetSlot5(SS_CARDTYPE NewCardType);
|
||||||
std::string BrowseToFile(HWND hWindow, TCHAR* pszTitle, TCHAR* REGVALUE,TCHAR* FILEMASKS);
|
std::string BrowseToFile(HWND hWindow, TCHAR* pszTitle, TCHAR* REGVALUE,TCHAR* FILEMASKS);
|
||||||
void SaveStateUpdate();
|
void SaveStateUpdate();
|
||||||
void GetDiskBaseNameWithAWS(TCHAR* pszFilename);
|
|
||||||
int SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bool bSave);
|
int SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bool bSave);
|
||||||
void PostMsgAfterClose(HWND hWnd, PAGETYPE page);
|
void PostMsgAfterClose(HWND hWnd, PAGETYPE page);
|
||||||
|
|
||||||
|
@ -37,17 +36,20 @@ public:
|
||||||
CConfigNeedingRestart& GetConfigNew(void) { return m_ConfigNew; }
|
CConfigNeedingRestart& GetConfigNew(void) { return m_ConfigNew; }
|
||||||
bool IsConfigChanged(void) { return m_ConfigNew != m_ConfigOld; }
|
bool IsConfigChanged(void) { return m_ConfigNew != m_ConfigOld; }
|
||||||
void SetDoBenchmark(void) { m_bDoBenchmark = true; }
|
void SetDoBenchmark(void) { m_bDoBenchmark = true; }
|
||||||
|
void ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool IsOkToSaveLoadState(HWND hWnd, const bool bConfigChanged);
|
bool IsOkToSaveLoadState(HWND hWnd, const bool bConfigChanged);
|
||||||
bool IsOkToRestart(HWND hWnd);
|
bool IsOkToRestart(HWND hWnd);
|
||||||
void SaveComputerType(eApple2Type NewApple2Type);
|
void SaveComputerType(eApple2Type NewApple2Type);
|
||||||
|
void SaveCpuType(eCpuType NewCpuType);
|
||||||
bool HardwareConfigChanged(HWND hWnd);
|
bool HardwareConfigChanged(HWND hWnd);
|
||||||
bool CheckChangesForRestart(HWND hWnd);
|
bool CheckChangesForRestart(HWND hWnd);
|
||||||
void ApplyNewConfig(void);
|
void ApplyNewConfig(void);
|
||||||
void RestoreCurrentConfig(void);
|
void RestoreCurrentConfig(void);
|
||||||
std::string GetSlot(const UINT uSlot);
|
std::string GetSlot(const UINT uSlot);
|
||||||
std::string GetCardName(const SS_CARDTYPE CardType);
|
std::string GetCardName(const SS_CARDTYPE CardType);
|
||||||
|
void GetDiskBaseNameWithAWS(TCHAR* pszFilename);
|
||||||
|
|
||||||
PAGETYPE m_LastPage;
|
PAGETYPE m_LastPage;
|
||||||
UINT32 m_bmPages;
|
UINT32 m_bmPages;
|
||||||
|
|
|
@ -1955,7 +1955,7 @@ Update_t CmdTraceFile (int nArgs)
|
||||||
fclose( g_hTraceFile );
|
fclose( g_hTraceFile );
|
||||||
g_hTraceFile = NULL;
|
g_hTraceFile = NULL;
|
||||||
|
|
||||||
sprintf( sText, "Trace stopped." );
|
_snprintf( sText, sizeof(sText), "Trace stopped." );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1975,16 +1975,17 @@ Update_t CmdTraceFile (int nArgs)
|
||||||
|
|
||||||
if (g_hTraceFile)
|
if (g_hTraceFile)
|
||||||
{
|
{
|
||||||
sprintf( sText, "Trace started: %s", sFilePath );
|
_snprintf( sText, sizeof(sText), "Trace started: %s", sFilePath );
|
||||||
|
|
||||||
g_bTraceHeader = true;
|
g_bTraceHeader = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf( sText, "Trace ERROR: %s", sFilePath );
|
_snprintf( sText, sizeof(sText), "Trace ERROR: %s", sFilePath );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sText[sizeof(sText)-1] = 0; // _snprintf needs null if string was longer than buffer
|
||||||
ConsoleBufferPush( sText );
|
ConsoleBufferPush( sText );
|
||||||
ConsoleBufferToDisplay();
|
ConsoleBufferToDisplay();
|
||||||
|
|
||||||
|
@ -2313,7 +2314,7 @@ void ConfigSave_PrepareHeader ( const Parameters_e eCategory, const Commands_e e
|
||||||
sprintf( sText, "%s %s = %s\n"
|
sprintf( sText, "%s %s = %s\n"
|
||||||
, g_aTokens[ TOKEN_COMMENT_EOL ].sToken
|
, g_aTokens[ TOKEN_COMMENT_EOL ].sToken
|
||||||
, g_aParameters[ PARAM_CATEGORY ].m_sName
|
, g_aParameters[ PARAM_CATEGORY ].m_sName
|
||||||
, g_aParameters[ eCategory ]
|
, g_aParameters[ eCategory ].m_sName
|
||||||
);
|
);
|
||||||
g_ConfigState.PushLine( sText );
|
g_ConfigState.PushLine( sText );
|
||||||
|
|
||||||
|
@ -4297,7 +4298,7 @@ Update_t CmdMemoryLoad (int nArgs)
|
||||||
TCHAR sLoadSaveFilePath[ MAX_PATH ];
|
TCHAR sLoadSaveFilePath[ MAX_PATH ];
|
||||||
_tcscpy( sLoadSaveFilePath, g_sCurrentDir ); // TODO: g_sDebugDir
|
_tcscpy( sLoadSaveFilePath, g_sCurrentDir ); // TODO: g_sDebugDir
|
||||||
|
|
||||||
WORD nAddressStart;
|
WORD nAddressStart = 0;
|
||||||
WORD nAddress2 = 0;
|
WORD nAddress2 = 0;
|
||||||
WORD nAddressEnd = 0;
|
WORD nAddressEnd = 0;
|
||||||
int nAddressLen = 0;
|
int nAddressLen = 0;
|
||||||
|
@ -4370,7 +4371,7 @@ Update_t CmdMemoryLoad (int nArgs)
|
||||||
|
|
||||||
if (bBankSpecified)
|
if (bBankSpecified)
|
||||||
{
|
{
|
||||||
MemUpdatePaging(1);
|
MemUpdatePaging(TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5975,6 +5976,7 @@ Update_t CmdOutputPrintf (int nArgs)
|
||||||
{
|
{
|
||||||
case '\\':
|
case '\\':
|
||||||
eThis = PS_ESCAPE;
|
eThis = PS_ESCAPE;
|
||||||
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
eThis = PS_TYPE;
|
eThis = PS_TYPE;
|
||||||
break;
|
break;
|
||||||
|
@ -7027,7 +7029,6 @@ Update_t CmdWindowViewCode (int nArgs)
|
||||||
Update_t CmdWindowViewConsole (int nArgs)
|
Update_t CmdWindowViewConsole (int nArgs)
|
||||||
{
|
{
|
||||||
return _CmdWindowViewFull( WINDOW_CONSOLE );
|
return _CmdWindowViewFull( WINDOW_CONSOLE );
|
||||||
return UPDATE_ALL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -7049,14 +7050,12 @@ Update_t CmdWindowViewOutput (int nArgs)
|
||||||
Update_t CmdWindowViewSource (int nArgs)
|
Update_t CmdWindowViewSource (int nArgs)
|
||||||
{
|
{
|
||||||
return _CmdWindowViewFull( WINDOW_CONSOLE );
|
return _CmdWindowViewFull( WINDOW_CONSOLE );
|
||||||
return UPDATE_ALL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
Update_t CmdWindowViewSymbols (int nArgs)
|
Update_t CmdWindowViewSymbols (int nArgs)
|
||||||
{
|
{
|
||||||
return _CmdWindowViewFull( WINDOW_CONSOLE );
|
return _CmdWindowViewFull( WINDOW_CONSOLE );
|
||||||
return UPDATE_ALL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -7771,7 +7770,7 @@ void OutputTraceLine ()
|
||||||
(unsigned)regs.sp,
|
(unsigned)regs.sp,
|
||||||
(char*) sFlags
|
(char*) sFlags
|
||||||
, sDisassembly
|
, sDisassembly
|
||||||
, sTarget
|
//, sTarget // TODO: Show target?
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "..\Structs.h"
|
#include "..\SaveState_Structs_v1.h" // For SS_CARD_MOCKINGBOARD
|
||||||
#include "..\Common.h"
|
#include "..\Common.h"
|
||||||
|
|
||||||
#include "Debugger_Types.h"
|
#include "Debugger_Types.h"
|
||||||
|
|
|
@ -565,7 +565,6 @@ bool _6502_GetStackReturnAddress ( WORD & nAddress_ )
|
||||||
|
|
||||||
if (nStack <= (_6502_STACK_END - 1))
|
if (nStack <= (_6502_STACK_END - 1))
|
||||||
{
|
{
|
||||||
nAddress_ = 0;
|
|
||||||
nAddress_ = (unsigned)*(LPBYTE)(mem + nStack);
|
nAddress_ = (unsigned)*(LPBYTE)(mem + nStack);
|
||||||
nStack++;
|
nStack++;
|
||||||
|
|
||||||
|
|
|
@ -40,345 +40,345 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
Command_t g_aCommands[] =
|
Command_t g_aCommands[] =
|
||||||
{
|
{
|
||||||
// Assembler
|
// Assembler
|
||||||
// {"!" , CmdAssemberMini , CMD_ASSEMBLER_MINI , "Mini assembler" }
|
// {TEXT("!") , CmdAssemberMini , CMD_ASSEMBLER_MINI , "Mini assembler" },
|
||||||
{"A" , CmdAssemble , CMD_ASSEMBLE , "Assemble instructions" }
|
{TEXT("A") , CmdAssemble , CMD_ASSEMBLE , "Assemble instructions" },
|
||||||
// CPU (Main)
|
// CPU (Main)
|
||||||
,{"." , CmdCursorJumpPC , CMD_CURSOR_JUMP_PC , "Locate the cursor in the disasm window" } // centered
|
{TEXT(".") , CmdCursorJumpPC , CMD_CURSOR_JUMP_PC , "Locate the cursor in the disasm window" }, // centered
|
||||||
,{"=" , CmdCursorSetPC , CMD_CURSOR_SET_PC , "Sets the PC to the current instruction" }
|
{TEXT("=") , CmdCursorSetPC , CMD_CURSOR_SET_PC , "Sets the PC to the current instruction" },
|
||||||
// ,{"g" , CmdGoNormalSpeed , CMD_GO_NORMAL , "Run @ normal speed [until PC == address]" }
|
// {TEXT("g") , CmdGoNormalSpeed , CMD_GO_NORMAL , "Run @ normal speed [until PC == address]" },
|
||||||
// ,{"G" , CmdGoFullSpeed , CMD_GO_FULL , "Run @ full speed [until PC == address]" }
|
// {TEXT("G") , CmdGoFullSpeed , CMD_GO_FULL , "Run @ full speed [until PC == address]" },
|
||||||
,{"G" , CmdGo , CMD_GO , "Run @ full speed [until PC == address]" }
|
{TEXT("G") , CmdGo , CMD_GO , "Run @ full speed [until PC == address]" },
|
||||||
,{"IN" , CmdIn , CMD_IN , "Input byte from IO $C0xx" }
|
{TEXT("IN") , CmdIn , CMD_IN , "Input byte from IO $C0xx" },
|
||||||
,{"KEY" , CmdKey , CMD_INPUT_KEY , "Feed key into emulator" }
|
{TEXT("KEY") , CmdKey , CMD_INPUT_KEY , "Feed key into emulator" },
|
||||||
,{"JSR" , CmdJSR , CMD_JSR , "Call sub-routine" }
|
{TEXT("JSR") , CmdJSR , CMD_JSR , "Call sub-routine" },
|
||||||
,{"NOP" , CmdNOP , CMD_NOP , "Zap the current instruction with a NOP" }
|
{TEXT("NOP") , CmdNOP , CMD_NOP , "Zap the current instruction with a NOP" },
|
||||||
,{"OUT" , CmdOut , CMD_OUT , "Output byte to IO $C0xx" }
|
{TEXT("OUT") , CmdOut , CMD_OUT , "Output byte to IO $C0xx" },
|
||||||
// CPU - Meta Info
|
// CPU - Meta Info
|
||||||
,{"PROFILE" , CmdProfile , CMD_PROFILE , "List/Save 6502 profiling" }
|
{TEXT("PROFILE") , CmdProfile , CMD_PROFILE , "List/Save 6502 profiling" },
|
||||||
,{"R" , CmdRegisterSet , CMD_REGISTER_SET , "Set register" }
|
{TEXT("R") , CmdRegisterSet , CMD_REGISTER_SET , "Set register" },
|
||||||
// CPU - Stack
|
// CPU - Stack
|
||||||
,{"POP" , CmdStackPop , CMD_STACK_POP }
|
{TEXT("POP") , CmdStackPop , CMD_STACK_POP },
|
||||||
,{"PPOP" , CmdStackPopPseudo , CMD_STACK_POP_PSEUDO }
|
{TEXT("PPOP") , CmdStackPopPseudo , CMD_STACK_POP_PSEUDO },
|
||||||
,{"PUSH" , CmdStackPop , CMD_STACK_PUSH }
|
{TEXT("PUSH") , CmdStackPop , CMD_STACK_PUSH },
|
||||||
// ,{"RTS" , CmdStackReturn , CMD_STACK_RETURN }
|
// {TEXT("RTS") , CmdStackReturn , CMD_STACK_RETURN },
|
||||||
,{"P" , CmdStepOver , CMD_STEP_OVER , "Step current instruction" }
|
{TEXT("P") , CmdStepOver , CMD_STEP_OVER , "Step current instruction" },
|
||||||
,{"RTS" , CmdStepOut , CMD_STEP_OUT , "Step out of subroutine" }
|
{TEXT("RTS") , CmdStepOut , CMD_STEP_OUT , "Step out of subroutine" },
|
||||||
// CPU - Meta Info
|
// CPU - Meta Info
|
||||||
,{"T" , CmdTrace , CMD_TRACE , "Trace current instruction" }
|
{TEXT("T") , CmdTrace , CMD_TRACE , "Trace current instruction" },
|
||||||
,{"TF" , CmdTraceFile , CMD_TRACE_FILE , "Save trace to filename" }
|
{TEXT("TF") , CmdTraceFile , CMD_TRACE_FILE , "Save trace to filename" },
|
||||||
,{"TL" , CmdTraceLine , CMD_TRACE_LINE , "Trace (with cycle counting)" }
|
{TEXT("TL") , CmdTraceLine , CMD_TRACE_LINE , "Trace (with cycle counting)" },
|
||||||
,{"U" , CmdUnassemble , CMD_UNASSEMBLE , "Disassemble instructions" }
|
{TEXT("U") , CmdUnassemble , CMD_UNASSEMBLE , "Disassemble instructions" },
|
||||||
// ,{"WAIT" , CmdWait , CMD_WAIT , "Run until"
|
// {TEXT("WAIT") , CmdWait , CMD_WAIT , "Run until
|
||||||
// Bookmarks
|
// Bookmarks
|
||||||
,{"BM" , CmdBookmark , CMD_BOOKMARK , "Alias for BMA (Bookmark Add)" }
|
{TEXT("BM") , CmdBookmark , CMD_BOOKMARK , "Alias for BMA (Bookmark Add)" },
|
||||||
,{"BMA" , CmdBookmarkAdd , CMD_BOOKMARK_ADD , "Add/Update addess to bookmark" }
|
{TEXT("BMA") , CmdBookmarkAdd , CMD_BOOKMARK_ADD , "Add/Update addess to bookmark" },
|
||||||
,{"BMC" , CmdBookmarkClear , CMD_BOOKMARK_CLEAR , "Clear (remove) bookmark" }
|
{TEXT("BMC") , CmdBookmarkClear , CMD_BOOKMARK_CLEAR , "Clear (remove) bookmark" },
|
||||||
,{"BML" , CmdBookmarkList , CMD_BOOKMARK_LIST , "List all bookmarks" }
|
{TEXT("BML") , CmdBookmarkList , CMD_BOOKMARK_LIST , "List all bookmarks" },
|
||||||
,{"BMG" , CmdBookmarkGoto , CMD_BOOKMARK_GOTO , "Move cursor to bookmark" }
|
{TEXT("BMG") , CmdBookmarkGoto , CMD_BOOKMARK_GOTO , "Move cursor to bookmark" },
|
||||||
// ,{"BMLOAD" , CmdBookmarkLoad , CMD_BOOKMARK_LOAD , "Load bookmarks" }
|
// {TEXT("BMLOAD") , CmdBookmarkLoad , CMD_BOOKMARK_LOAD , "Load bookmarks" },
|
||||||
,{"BMSAVE" , CmdBookmarkSave , CMD_BOOKMARK_SAVE , "Save bookmarks" }
|
{TEXT("BMSAVE") , CmdBookmarkSave , CMD_BOOKMARK_SAVE , "Save bookmarks" },
|
||||||
// Breakpoints
|
// Breakpoints
|
||||||
,{"BRK" , CmdBreakInvalid , CMD_BREAK_INVALID , "Enter debugger on BRK or INVALID" }
|
{TEXT("BRK") , CmdBreakInvalid , CMD_BREAK_INVALID , "Enter debugger on BRK or INVALID" },
|
||||||
,{"BRKOP" , CmdBreakOpcode , CMD_BREAK_OPCODE , "Enter debugger on opcode" }
|
{TEXT("BRKOP") , CmdBreakOpcode , CMD_BREAK_OPCODE , "Enter debugger on opcode" },
|
||||||
,{"BP" , CmdBreakpoint , CMD_BREAKPOINT , "Alias for BPR (Breakpoint Register Add)" }
|
{TEXT("BP") , CmdBreakpoint , CMD_BREAKPOINT , "Alias for BPR (Breakpoint Register Add)" },
|
||||||
,{"BPA" , CmdBreakpointAddSmart , CMD_BREAKPOINT_ADD_SMART , "Add (smart) breakpoint" }
|
{TEXT("BPA") , CmdBreakpointAddSmart, CMD_BREAKPOINT_ADD_SMART , "Add (smart) breakpoint" },
|
||||||
// ,{"BPP" , CmdBreakpointAddFlag , CMD_BREAKPOINT_ADD_FLAG , "Add breakpoint on flags" }
|
// {TEXT("BPP") , CmdBreakpointAddFlag , CMD_BREAKPOINT_ADD_FLAG , "Add breakpoint on flags" },
|
||||||
,{"BPR" , CmdBreakpointAddReg , CMD_BREAKPOINT_ADD_REG , "Add breakpoint on register value" } // NOTE! Different from SoftICE !!!!
|
{TEXT("BPR") , CmdBreakpointAddReg , CMD_BREAKPOINT_ADD_REG , "Add breakpoint on register value" }, // NOTE! Different from SoftICE !!!!
|
||||||
,{"BPX" , CmdBreakpointAddPC , CMD_BREAKPOINT_ADD_PC , "Add breakpoint at current instruction" }
|
{TEXT("BPX") , CmdBreakpointAddPC , CMD_BREAKPOINT_ADD_PC , "Add breakpoint at current instruction" },
|
||||||
,{"BPIO" , CmdBreakpointAddIO , CMD_BREAKPOINT_ADD_IO , "Add breakpoint for IO address $C0xx" }
|
{TEXT("BPIO") , CmdBreakpointAddIO , CMD_BREAKPOINT_ADD_IO , "Add breakpoint for IO address $C0xx" },
|
||||||
,{"BPM" , CmdBreakpointAddMem , CMD_BREAKPOINT_ADD_MEM , "Add breakpoint on memory access" } // SoftICE
|
{TEXT("BPM") , CmdBreakpointAddMem , CMD_BREAKPOINT_ADD_MEM , "Add breakpoint on memory access" }, // SoftICE
|
||||||
|
|
||||||
,{"BPC" , CmdBreakpointClear , CMD_BREAKPOINT_CLEAR , "Clear (remove) breakpoint" } // SoftICE
|
{TEXT("BPC") , CmdBreakpointClear , CMD_BREAKPOINT_CLEAR , "Clear (remove) breakpoint" }, // SoftICE
|
||||||
,{"BPD" , CmdBreakpointDisable , CMD_BREAKPOINT_DISABLE , "Disable breakpoint- it is still in the list, just not active" } // SoftICE
|
{TEXT("BPD") , CmdBreakpointDisable , CMD_BREAKPOINT_DISABLE , "Disable breakpoint- it is still in the list, just not active" }, // SoftICE
|
||||||
,{"BPEDIT" , CmdBreakpointEdit , CMD_BREAKPOINT_EDIT , "Edit breakpoint" } // SoftICE
|
{TEXT("BPEDIT") , CmdBreakpointEdit , CMD_BREAKPOINT_EDIT , "Edit breakpoint" }, // SoftICE
|
||||||
,{"BPE" , CmdBreakpointEnable , CMD_BREAKPOINT_ENABLE , "(Re)Enable disabled breakpoint" } // SoftICE
|
{TEXT("BPE") , CmdBreakpointEnable , CMD_BREAKPOINT_ENABLE , "(Re)Enable disabled breakpoint" }, // SoftICE
|
||||||
,{"BPL" , CmdBreakpointList , CMD_BREAKPOINT_LIST , "List all breakpoints" } // SoftICE
|
{TEXT("BPL") , CmdBreakpointList , CMD_BREAKPOINT_LIST , "List all breakpoints" }, // SoftICE
|
||||||
// ,{"BPLOAD" , CmdBreakpointLoad , CMD_BREAKPOINT_LOAD , "Loads breakpoints" }
|
// {TEXT("BPLOAD") , CmdBreakpointLoad , CMD_BREAKPOINT_LOAD , "Loads breakpoints" },
|
||||||
,{"BPSAVE" , CmdBreakpointSave , CMD_BREAKPOINT_SAVE , "Saves breakpoints" }
|
{TEXT("BPSAVE") , CmdBreakpointSave , CMD_BREAKPOINT_SAVE , "Saves breakpoints" },
|
||||||
// Config
|
// Config
|
||||||
,{"BENCHMARK" , CmdBenchmark , CMD_BENCHMARK , "Benchmark the emulator" }
|
{TEXT("BENCHMARK") , CmdBenchmark , CMD_BENCHMARK , "Benchmark the emulator" },
|
||||||
,{"BW" , CmdConfigColorMono , CMD_CONFIG_BW , "Sets/Shows RGB for Black & White scheme" }
|
{TEXT("BW") , CmdConfigColorMono , CMD_CONFIG_BW , "Sets/Shows RGB for Black & White scheme" },
|
||||||
,{"COLOR" , CmdConfigColorMono , CMD_CONFIG_COLOR , "Sets/Shows RGB for color scheme" }
|
{TEXT("COLOR") , CmdConfigColorMono , CMD_CONFIG_COLOR , "Sets/Shows RGB for color scheme" },
|
||||||
// ,{"OPTION" , CmdConfigMenu , CMD_CONFIG_MENU , "Access config options" }
|
// {TEXT("OPTION") , CmdConfigMenu , CMD_CONFIG_MENU , "Access config options" },
|
||||||
,{"DISASM" , CmdConfigDisasm , CMD_CONFIG_DISASM , "Sets/Shows disassembly view options." }
|
{TEXT("DISASM") , CmdConfigDisasm , CMD_CONFIG_DISASM , "Sets/Shows disassembly view options." },
|
||||||
,{"FONT" , CmdConfigFont , CMD_CONFIG_FONT , "Shows current font or sets new one" }
|
{TEXT("FONT") , CmdConfigFont , CMD_CONFIG_FONT , "Shows current font or sets new one" },
|
||||||
,{"HCOLOR" , CmdConfigHColor , CMD_CONFIG_HCOLOR , "Sets/Shows colors mapped to Apple HGR" }
|
{TEXT("HCOLOR") , CmdConfigHColor , CMD_CONFIG_HCOLOR , "Sets/Shows colors mapped to Apple HGR" },
|
||||||
,{"LOAD" , CmdConfigLoad , CMD_CONFIG_LOAD , "Load debugger configuration" }
|
{TEXT("LOAD") , CmdConfigLoad , CMD_CONFIG_LOAD , "Load debugger configuration" },
|
||||||
,{"MONO" , CmdConfigColorMono , CMD_CONFIG_MONOCHROME , "Sets/Shows RGB for monochrome scheme" }
|
{TEXT("MONO") , CmdConfigColorMono , CMD_CONFIG_MONOCHROME , "Sets/Shows RGB for monochrome scheme" },
|
||||||
,{"SAVE" , CmdConfigSave , CMD_CONFIG_SAVE , "Save debugger configuration" }
|
{TEXT("SAVE") , CmdConfigSave , CMD_CONFIG_SAVE , "Save debugger configuration" },
|
||||||
,{"PWD" , CmdConfigGetDebugDir , CMD_CONFIG_GET_DEBUG_DIR , "Display current debugger directory for scripts & mem load/save." }
|
{TEXT("PWD") , CmdConfigGetDebugDir , CMD_CONFIG_GET_DEBUG_DIR , "Displays the current debugger directory. Used for scripts & mem load/save." },
|
||||||
,{"CD" , CmdConfigSetDebugDir , CMD_CONFIG_SET_DEBUG_DIR , "Update current debugger directory." }
|
{TEXT("CD") , CmdConfigSetDebugDir , CMD_CONFIG_SET_DEBUG_DIR , "Updates the current debugger directory." },
|
||||||
// Cursor
|
// Cursor
|
||||||
,{"RET" , CmdCursorJumpRetAddr , CMD_CURSOR_JUMP_RET_ADDR , "Sets the cursor to the subroutine caller" }
|
{TEXT("RET") , CmdCursorJumpRetAddr , CMD_CURSOR_JUMP_RET_ADDR , "Sets the cursor to the sub-routine caller" },
|
||||||
,{ "^" , NULL , CMD_CURSOR_LINE_UP } // \x2191 = Up Arrow (Unicode)
|
{TEXT( "^") , NULL , CMD_CURSOR_LINE_UP }, // \x2191 = Up Arrow (Unicode)
|
||||||
,{"Shift ^" , NULL , CMD_CURSOR_LINE_UP_1 }
|
{TEXT("Shift ^") , NULL , CMD_CURSOR_LINE_UP_1 },
|
||||||
,{ "v" , NULL , CMD_CURSOR_LINE_DOWN } // \x2193 = Dn Arrow (Unicode)
|
{TEXT( "v") , NULL , CMD_CURSOR_LINE_DOWN }, // \x2193 = Dn Arrow (Unicode)
|
||||||
,{"Shift v" , NULL , CMD_CURSOR_LINE_DOWN_1 }
|
{TEXT("Shift v") , NULL , CMD_CURSOR_LINE_DOWN_1 },
|
||||||
,{"PAGEUP" , CmdCursorPageUp , CMD_CURSOR_PAGE_UP , "Scroll up one screen" }
|
{TEXT("PAGEUP" ) , CmdCursorPageUp , CMD_CURSOR_PAGE_UP , "Scroll up one screen" },
|
||||||
,{"PAGEUP256" , CmdCursorPageUp256 , CMD_CURSOR_PAGE_UP_256 , "Scroll up 256 bytes" } // Shift
|
{TEXT("PAGEUP256") , CmdCursorPageUp256 , CMD_CURSOR_PAGE_UP_256 , "Scroll up 256 bytes" }, // Shift
|
||||||
,{"PAGEUP4K" , CmdCursorPageUp4K , CMD_CURSOR_PAGE_UP_4K , "Scroll up 4096 bytes" } // Ctrl
|
{TEXT("PAGEUP4K" ) , CmdCursorPageUp4K , CMD_CURSOR_PAGE_UP_4K , "Scroll up 4096 bytes" }, // Ctrl
|
||||||
,{"PAGEDN" , CmdCursorPageDown , CMD_CURSOR_PAGE_DOWN , "Scroll down one scren" }
|
{TEXT("PAGEDN" ) , CmdCursorPageDown , CMD_CURSOR_PAGE_DOWN , "Scroll down one scren" },
|
||||||
,{"PAGEDOWN256" , CmdCursorPageDown256 , CMD_CURSOR_PAGE_DOWN_256 , "Scroll down 256 bytes" } // Shift
|
{TEXT("PAGEDOWN256") , CmdCursorPageDown256 , CMD_CURSOR_PAGE_DOWN_256 , "Scroll down 256 bytes" }, // Shift
|
||||||
,{"PAGEDOWN4K" , CmdCursorPageDown4K , CMD_CURSOR_PAGE_DOWN_4K , "Scroll down 4096 bytes" } // Ctrl
|
{TEXT("PAGEDOWN4K" ) , CmdCursorPageDown4K , CMD_CURSOR_PAGE_DOWN_4K , "Scroll down 4096 bytes" }, // Ctrl
|
||||||
// Disassembler Data
|
// Disassembler Data
|
||||||
,{"Z" , CmdDisasmDataDefByte1 , CMD_DISASM_DATA , "Treat byte [range] as data" }
|
{TEXT("Z") , CmdDisasmDataDefByte1 , CMD_DISASM_DATA , "Treat byte [range] as data" },
|
||||||
,{"X" , CmdDisasmDataDefCode , CMD_DISASM_CODE , "Treat byte [range] as code" }
|
{TEXT("X") , CmdDisasmDataDefCode , CMD_DISASM_CODE , "Treat byte [range] as code" },
|
||||||
// TODO: Conflicts with monitor command #L -> 000DL
|
// TODO: Conflicts with monitor command #L -> 000DL
|
||||||
,{"B" , CmdDisasmDataList , CMD_DISASM_LIST , "List all byte ranges treated as data" }
|
{TEXT("B") , CmdDisasmDataList , CMD_DISASM_LIST , "List all byte ranges treated as data" },
|
||||||
// without symbol lookup
|
// without symbol lookup
|
||||||
,{"DB" , CmdDisasmDataDefByte1 , CMD_DEFINE_DATA_BYTE1 , "Define byte(s)" }
|
{TEXT("DB") , CmdDisasmDataDefByte1 , CMD_DEFINE_DATA_BYTE1, "Define byte(s)" },
|
||||||
,{"DB2" , CmdDisasmDataDefByte2 , CMD_DEFINE_DATA_BYTE2 , "Define byte array, display 2 bytes/line" }
|
{TEXT("DB2") , CmdDisasmDataDefByte2 , CMD_DEFINE_DATA_BYTE2, "Define byte array, display 2 bytes/line" },
|
||||||
,{"DB4" , CmdDisasmDataDefByte4 , CMD_DEFINE_DATA_BYTE4 , "Define byte array, display 4 bytes/line" }
|
{TEXT("DB4") , CmdDisasmDataDefByte4 , CMD_DEFINE_DATA_BYTE4, "Define byte array, display 4 bytes/line" },
|
||||||
,{"DB8" , CmdDisasmDataDefByte8 , CMD_DEFINE_DATA_BYTE8 , "Define byte array, display 8 bytes/line" }
|
{TEXT("DB8") , CmdDisasmDataDefByte8 , CMD_DEFINE_DATA_BYTE8, "Define byte array, display 8 bytes/line" },
|
||||||
,{"DW" , CmdDisasmDataDefWord1 , CMD_DEFINE_DATA_WORD1 , "Define address array" }
|
{TEXT("DW") , CmdDisasmDataDefWord1 , CMD_DEFINE_DATA_WORD1, "Define address array" },
|
||||||
,{"DW2" , CmdDisasmDataDefWord2 , CMD_DEFINE_DATA_WORD2 , "Define address array, display 2 words/line" }
|
{TEXT("DW2") , CmdDisasmDataDefWord2 , CMD_DEFINE_DATA_WORD2, "Define address array, display 2 words/line" },
|
||||||
,{"DW4" , CmdDisasmDataDefWord4 , CMD_DEFINE_DATA_WORD4 , "Define address array, display 4 words/line" }
|
{TEXT("DW4") , CmdDisasmDataDefWord4 , CMD_DEFINE_DATA_WORD4, "Define address array, display 4 words/line" },
|
||||||
,{"ASC" , CmdDisasmDataDefString , CMD_DEFINE_DATA_STR , "Define text string" } // 2.7.0.26 Changed: DS to ASC because DS is used as "Define Space" assembler directive
|
{TEXT("ASC") , CmdDisasmDataDefString , CMD_DEFINE_DATA_STR , "Define text string" }, // 2.7.0.26 Changed: DS to ASC because DS is used as "Define Space" assembler directive
|
||||||
// .{"DF" , CmdDisasmDataDefFloat , CMD_DEFINE_DATA_FLOAT , "Define AppleSoft (packed) Float" }
|
// {TEXT("DF") , CmdDisasmDataDefFloat , CMD_DEFINE_DATA_FLOAT, "Define AppleSoft (packed) Float" },
|
||||||
// .{"DFX" , CmdDisasmDataDefFloatUnpack , CMD_DEFINE_DATA_FLOAT2 , "Define AppleSoft (unpacked) Float" }
|
// {TEXT("DFX") , CmdDisasmDataDefFloatUnpack , CMD_DEFINE_DATA_FLOAT2,"Define AppleSoft (unpacked) Float" },
|
||||||
// with symbol lookup
|
// with symbol lookup
|
||||||
// .{"DA<>" , CmdDisasmDataDefAddress8HL , CMD_DEFINE_ADDR_8_HL , "Define split array of addresses, high byte section followed by low byte section" }
|
// {TEXT("DA<>") , CmdDisasmDataDefAddress8HL , CMD_DEFINE_ADDR_8_HL , "Define split array of addresses, high byte section followed by low byte section" },
|
||||||
// .{"DA><" , CmdDisasmDataDefAddress8LH , CMD_DEFINE_ADDR_8_LH , "Define split array of addresses, low byte section followed by high byte section" }
|
// {TEXT("DA><") , CmdDisasmDataDefAddress8LH , CMD_DEFINE_ADDR_8_LH , "Define split array of addresses, low byte section followed by high byte section" },
|
||||||
// .{"DA<" , CmdDisasmDataDefAddress8H , CMD_DEFINE_ADDR_BYTE_H , "Define array of high byte addresses" }
|
// {TEXT("DA<") , CmdDisasmDataDefAddress8H , CMD_DEFINE_ADDR_BYTE_H , "Define array of high byte addresses" },
|
||||||
// .{"DB>" , CmdDisasmDataDefAddress8L , CMD_DEFINE_ADDR_BYTE_L , "Define array of low byte addresses" }
|
// {TEXT("DB>") , CmdDisasmDataDefAddress8L , CMD_DEFINE_ADDR_BYTE_L , "Define array of low byte addresses" }
|
||||||
,{"DA" , CmdDisasmDataDefAddress16 , CMD_DEFINE_ADDR_WORD , "Define array of word addresses" }
|
{TEXT("DA") , CmdDisasmDataDefAddress16 , CMD_DEFINE_ADDR_WORD , "Define array of word addresses" },
|
||||||
// TODO: Rename config cmd: DISASM
|
// TODO: Rename config cmd: DISASM
|
||||||
// {"UA" , CmdDisasmDataSmart , CMD_SMART_DISASSEMBLE , "Analyze opcodes to determine if code or data" }
|
// {TEXT("UA") , CmdDisasmDataSmart , CMD_SMART_DISASSEMBLE, "Analyze opcodes to determine if code or data" },
|
||||||
// Disk
|
// Disk
|
||||||
,{"DISK" , CmdDisk , CMD_DISK , "Access Disk Drive Functions" }
|
{TEXT("DISK") , CmdDisk , CMD_DISK , "Access Disk Drive Functions" },
|
||||||
// Flags
|
// Flags
|
||||||
// {"FC" , CmdFlag , CMD_FLAG_CLEAR , "Clear specified Flag" } // NVRBDIZC see AW_CPU.cpp AF_*
|
// {TEXT("FC") , CmdFlag , CMD_FLAG_CLEAR , "Clear specified Flag" }, // NVRBDIZC see AW_CPU.cpp AF_*
|
||||||
// TODO: Conflicts with monitor command #L -> 000CL
|
// TODO: Conflicts with monitor command #L -> 000CL
|
||||||
,{"CL" , CmdFlag , CMD_FLAG_CLEAR , "Clear specified Flag" } // NVRBDIZC see AW_CPU.cpp AF_*
|
{TEXT("CL") , CmdFlag , CMD_FLAG_CLEAR , "Clear specified Flag" }, // NVRBDIZC see AW_CPU.cpp AF_*
|
||||||
|
|
||||||
,{"CLC" , CmdFlagClear , CMD_FLAG_CLR_C , "Clear Flag Carry" } // 0 // Legacy
|
{TEXT("CLC") , CmdFlagClear , CMD_FLAG_CLR_C , "Clear Flag Carry" }, // 0 // Legacy
|
||||||
,{"CLZ" , CmdFlagClear , CMD_FLAG_CLR_Z , "Clear Flag Zero" } // 1
|
{TEXT("CLZ") , CmdFlagClear , CMD_FLAG_CLR_Z , "Clear Flag Zero" }, // 1
|
||||||
,{"CLI" , CmdFlagClear , CMD_FLAG_CLR_I , "Clear Flag Interrupts Disabled" } // 2
|
{TEXT("CLI") , CmdFlagClear , CMD_FLAG_CLR_I , "Clear Flag Interrupts Disabled" }, // 2
|
||||||
,{"CLD" , CmdFlagClear , CMD_FLAG_CLR_D , "Clear Flag Decimal (BCD)" } // 3
|
{TEXT("CLD") , CmdFlagClear , CMD_FLAG_CLR_D , "Clear Flag Decimal (BCD)" }, // 3
|
||||||
,{"CLB" , CmdFlagClear , CMD_FLAG_CLR_B , "CLear Flag Break" } // 4 // Legacy
|
{TEXT("CLB") , CmdFlagClear , CMD_FLAG_CLR_B , "CLear Flag Break" }, // 4 // Legacy
|
||||||
,{"CLR" , CmdFlagClear , CMD_FLAG_CLR_R , "Clear Flag Reserved" } // 5
|
{TEXT("CLR") , CmdFlagClear , CMD_FLAG_CLR_R , "Clear Flag Reserved" }, // 5
|
||||||
,{"CLV" , CmdFlagClear , CMD_FLAG_CLR_V , "Clear Flag Overflow" } // 6
|
{TEXT("CLV") , CmdFlagClear , CMD_FLAG_CLR_V , "Clear Flag Overflow" }, // 6
|
||||||
,{"CLN" , CmdFlagClear , CMD_FLAG_CLR_N , "Clear Flag Negative (Sign)" } // 7
|
{TEXT("CLN") , CmdFlagClear , CMD_FLAG_CLR_N , "Clear Flag Negative (Sign)" }, // 7
|
||||||
|
|
||||||
// ,{"FS" , CmdFlag , CMD_FLAG_SET , "Set specified Flag" }
|
// {TEXT("FS") , CmdFlag , CMD_FLAG_SET , "Set specified Flag" },
|
||||||
,{"SE" , CmdFlag , CMD_FLAG_SET , "Set specified Flag" }
|
{TEXT("SE") , CmdFlag , CMD_FLAG_SET , "Set specified Flag" },
|
||||||
|
|
||||||
,{"SEC" , CmdFlagSet , CMD_FLAG_SET_C , "Set Flag Carry" } // 0
|
{TEXT("SEC") , CmdFlagSet , CMD_FLAG_SET_C , "Set Flag Carry" }, // 0
|
||||||
,{"SEZ" , CmdFlagSet , CMD_FLAG_SET_Z , "Set Flag Zero" } // 1
|
{TEXT("SEZ") , CmdFlagSet , CMD_FLAG_SET_Z , "Set Flag Zero" }, // 1
|
||||||
,{"SEI" , CmdFlagSet , CMD_FLAG_SET_I , "Set Flag Interrupts Disabled" } // 2
|
{TEXT("SEI") , CmdFlagSet , CMD_FLAG_SET_I , "Set Flag Interrupts Disabled" }, // 2
|
||||||
,{"SED" , CmdFlagSet , CMD_FLAG_SET_D , "Set Flag Decimal (BCD)" } // 3
|
{TEXT("SED") , CmdFlagSet , CMD_FLAG_SET_D , "Set Flag Decimal (BCD)" }, // 3
|
||||||
,{"SEB" , CmdFlagSet , CMD_FLAG_SET_B , "Set Flag Break" } // 4 // Legacy
|
{TEXT("SEB") , CmdFlagSet , CMD_FLAG_SET_B , "Set Flag Break" }, // 4 // Legacy
|
||||||
,{"SER" , CmdFlagSet , CMD_FLAG_SET_R , "Set Flag Reserved" } // 5
|
{TEXT("SER") , CmdFlagSet , CMD_FLAG_SET_R , "Set Flag Reserved" }, // 5
|
||||||
,{"SEV" , CmdFlagSet , CMD_FLAG_SET_V , "Set Flag Overflow" } // 6
|
{TEXT("SEV") , CmdFlagSet , CMD_FLAG_SET_V , "Set Flag Overflow" }, // 6
|
||||||
,{"SEN" , CmdFlagSet , CMD_FLAG_SET_N , "Set Flag Negative" } // 7
|
{TEXT("SEN") , CmdFlagSet , CMD_FLAG_SET_N , "Set Flag Negative" }, // 7
|
||||||
// Help
|
// Help
|
||||||
,{"?" , CmdHelpList , CMD_HELP_LIST , "List all available commands" }
|
{TEXT("?") , CmdHelpList , CMD_HELP_LIST , "List all available commands" },
|
||||||
,{"HELP" , CmdHelpSpecific , CMD_HELP_SPECIFIC , "Help on specific command" }
|
{TEXT("HELP") , CmdHelpSpecific , CMD_HELP_SPECIFIC , "Help on specific command" },
|
||||||
,{"VERSION" , CmdVersion , CMD_VERSION , "Displays version of emulator/debugger" }
|
{TEXT("VERSION") , CmdVersion , CMD_VERSION , "Displays version of emulator/debugger" },
|
||||||
,{"MOTD" , CmdMOTD , CMD_MOTD } // MOTD: Message Of The Day
|
{TEXT("MOTD") , CmdMOTD , CMD_MOTD }, // MOTD: Message Of The Day
|
||||||
// Memory
|
// Memory
|
||||||
,{"MC" , CmdMemoryCompare , CMD_MEMORY_COMPARE }
|
{TEXT("MC") , CmdMemoryCompare , CMD_MEMORY_COMPARE },
|
||||||
|
|
||||||
,{"MD1" , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 , "Hex dump in the mini memory area 1" }
|
{TEXT("MD1") , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 , "Hex dump in the mini memory area 1" },
|
||||||
,{"MD2" , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_2 , "Hex dump in the mini memory area 2" }
|
{TEXT("MD2") , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_2 , "Hex dump in the mini memory area 2" },
|
||||||
|
|
||||||
,{"MA1" , CmdMemoryMiniDumpAscii , CMD_MEM_MINI_DUMP_ASCII_1 , "ASCII text in mini memory area 1" }
|
{TEXT("MA1") , CmdMemoryMiniDumpAscii,CMD_MEM_MINI_DUMP_ASCII_1, "ASCII text in mini memory area 1" },
|
||||||
,{"MA2" , CmdMemoryMiniDumpAscii , CMD_MEM_MINI_DUMP_ASCII_2 , "ASCII text in mini memory area 2" }
|
{TEXT("MA2") , CmdMemoryMiniDumpAscii,CMD_MEM_MINI_DUMP_ASCII_2, "ASCII text in mini memory area 2" },
|
||||||
,{"MT1" , CmdMemoryMiniDumpApple , CMD_MEM_MINI_DUMP_APPLE_1 , "Apple Text in mini memory area 1" }
|
{TEXT("MT1") , CmdMemoryMiniDumpApple,CMD_MEM_MINI_DUMP_APPLE_1, "Apple Text in mini memory area 1" },
|
||||||
,{"MT2" , CmdMemoryMiniDumpApple , CMD_MEM_MINI_DUMP_APPLE_2 , "Apple Text in mini memory area 2" }
|
{TEXT("MT2") , CmdMemoryMiniDumpApple,CMD_MEM_MINI_DUMP_APPLE_2, "Apple Text in mini memory area 2" },
|
||||||
// {"ML1" , CmdMemoryMiniDumpLow , CMD_MEM_MINI_DUMP_TXT_LO_1 , "Text (Ctrl) in mini memory dump area 1" }
|
// {TEXT("ML1") , CmdMemoryMiniDumpLow , CMD_MEM_MINI_DUMP_TXT_LO_1, "Text (Ctrl) in mini memory dump area 1" },
|
||||||
// {"ML2" , CmdMemoryMiniDumpLow , CMD_MEM_MINI_DUMP_TXT_LO_2 , "Text (Ctrl) in mini memory dump area 2" }
|
// {TEXT("ML2") , CmdMemoryMiniDumpLow , CMD_MEM_MINI_DUMP_TXT_LO_2, "Text (Ctrl) in mini memory dump area 2" },
|
||||||
// {"MH1" , CmdMemoryMiniDumpHigh , CMD_MEM_MINI_DUMP_TXT_HI_1 , "Text (High) in mini memory dump area 1" }
|
// {TEXT("MH1") , CmdMemoryMiniDumpHigh, CMD_MEM_MINI_DUMP_TXT_HI_1, "Text (High) in mini memory dump area 1" },
|
||||||
// {"MH2" , CmdMemoryMiniDumpHigh , CMD_MEM_MINI_DUMP_TXT_HI_2 , "Text (High) in mini memory dump area 2" }
|
// {TEXT("MH2") , CmdMemoryMiniDumpHigh, CMD_MEM_MINI_DUMP_TXT_HI_2, "Text (High) in mini memory dump area 2" },
|
||||||
|
|
||||||
,{"ME" , CmdMemoryEdit , CMD_MEMORY_EDIT , "Memory Editor - Not Implemented!" } // TODO: like Copy ][+ Sector Edit
|
{TEXT("ME") , CmdMemoryEdit , CMD_MEMORY_EDIT , "Memory Editor - Not Implemented!" }, // TODO: like Copy ][+ Sector Edit
|
||||||
,{"MEB" , CmdMemoryEnterByte , CMD_MEMORY_ENTER_BYTE , "Enter byte" }
|
{TEXT("MEB") , CmdMemoryEnterByte , CMD_MEMORY_ENTER_BYTE , "Enter byte" },
|
||||||
,{"MEW" , CmdMemoryEnterWord , CMD_MEMORY_ENTER_WORD , "Enter word" }
|
{TEXT("MEW") , CmdMemoryEnterWord , CMD_MEMORY_ENTER_WORD , "Enter word" },
|
||||||
,{"BLOAD" , CmdMemoryLoad , CMD_MEMORY_LOAD , "Load a region of memory" }
|
{TEXT("BLOAD") , CmdMemoryLoad , CMD_MEMORY_LOAD , "Load a region of memory" },
|
||||||
,{"M" , CmdMemoryMove , CMD_MEMORY_MOVE , "Memory move" }
|
{TEXT("M") , CmdMemoryMove , CMD_MEMORY_MOVE , "Memory move" },
|
||||||
,{"BSAVE" , CmdMemorySave , CMD_MEMORY_SAVE , "Save a region of memory" }
|
{TEXT("BSAVE") , CmdMemorySave , CMD_MEMORY_SAVE , "Save a region of memory" },
|
||||||
,{"S" , CmdMemorySearch , CMD_MEMORY_SEARCH , "Search memory for text / hex values" }
|
{TEXT("S") , CmdMemorySearch , CMD_MEMORY_SEARCH , "Search memory for text / hex values" },
|
||||||
,{"@" ,_SearchMemoryDisplay , CMD_MEMORY_FIND_RESULTS , "Display search memory results" }
|
{TEXT("@") ,_SearchMemoryDisplay , CMD_MEMORY_FIND_RESULTS , "Display search memory results" },
|
||||||
// ,{"SA" , CmdMemorySearchAscii , CMD_MEMORY_SEARCH_ASCII , "Search ASCII text" }
|
// {TEXT("SA") , CmdMemorySearchAscii, CMD_MEMORY_SEARCH_ASCII , "Search ASCII text" },
|
||||||
// ,{"ST" , CmdMemorySearchApple , CMD_MEMORY_SEARCH_APPLE , "Search Apple text (hi-bit)" }
|
// {TEXT("ST") , CmdMemorySearchApple , CMD_MEMORY_SEARCH_APPLE , "Search Apple text (hi-bit)" },
|
||||||
,{"SH" , CmdMemorySearchHex , CMD_MEMORY_SEARCH_HEX , "Search memory for hex values" }
|
{TEXT("SH") , CmdMemorySearchHex , CMD_MEMORY_SEARCH_HEX , "Search memory for hex values" },
|
||||||
,{"F" , CmdMemoryFill , CMD_MEMORY_FILL , "Memory fill" }
|
{TEXT("F") , CmdMemoryFill , CMD_MEMORY_FILL , "Memory fill" },
|
||||||
|
|
||||||
,{"NTSC" , CmdNTSC , CMD_NTSC , "Save/Load the NTSC palette" }
|
{TEXT("NTSC") , CmdNTSC , CMD_NTSC , "Save/Load the NTSC palette" },
|
||||||
,{"TSAVE" , CmdTextSave , CMD_TEXT_SAVE , "Save text screen" }
|
{TEXT("TSAVE") , CmdTextSave , CMD_TEXT_SAVE , "Save text screen" },
|
||||||
// Output / Scripts
|
// Output / Scripts
|
||||||
,{"CALC" , CmdOutputCalc , CMD_OUTPUT_CALC , "Display mini calc result" }
|
{TEXT("CALC") , CmdOutputCalc , CMD_OUTPUT_CALC , "Display mini calc result" },
|
||||||
,{"ECHO" , CmdOutputEcho , CMD_OUTPUT_ECHO , "Echo string to console" } // or toggle command echoing"
|
{TEXT("ECHO") , CmdOutputEcho , CMD_OUTPUT_ECHO , "Echo string to console" }, // or toggle command echoing"
|
||||||
,{"PRINT" , CmdOutputPrint , CMD_OUTPUT_PRINT , "Display string and/or hex values" }
|
{TEXT("PRINT") , CmdOutputPrint , CMD_OUTPUT_PRINT , "Display string and/or hex values" },
|
||||||
,{"PRINTF" , CmdOutputPrintf , CMD_OUTPUT_PRINTF , "Display formatted string" }
|
{TEXT("PRINTF") , CmdOutputPrintf , CMD_OUTPUT_PRINTF , "Display formatted string" },
|
||||||
,{"RUN" , CmdOutputRun , CMD_OUTPUT_RUN , "Run script file of debugger commands" }
|
{TEXT("RUN") , CmdOutputRun , CMD_OUTPUT_RUN , "Run script file of debugger commands" },
|
||||||
// Source Level Debugging
|
// Source Level Debugging
|
||||||
,{"SOURCE" , CmdSource , CMD_SOURCE , "Starts/Stops source level debugging" }
|
{TEXT("SOURCE") , CmdSource , CMD_SOURCE , "Starts/Stops source level debugging" },
|
||||||
,{"SYNC" , CmdSync , CMD_SYNC , "Syncs the cursor to the source file" }
|
{TEXT("SYNC") , CmdSync , CMD_SYNC , "Syncs the cursor to the source file" },
|
||||||
// Symbols
|
// Symbols
|
||||||
,{"SYM" , CmdSymbols , CMD_SYMBOLS_LOOKUP , "Lookup symbol or address, or define symbol" }
|
{TEXT("SYM") , CmdSymbols , CMD_SYMBOLS_LOOKUP , "Lookup symbol or address, or define symbol" },
|
||||||
|
|
||||||
,{"SYMMAIN" , CmdSymbolsCommand , CMD_SYMBOLS_ROM , "Main/ROM symbol table lookup/menu" } // CLEAR,LOAD,SAVE
|
{"SYMMAIN" , CmdSymbolsCommand , CMD_SYMBOLS_ROM , "Main/ROM symbol table lookup/menu" }, // CLEAR,LOAD,SAVE
|
||||||
,{"SYMBASIC" , CmdSymbolsCommand , CMD_SYMBOLS_APPLESOFT , "Applesoft symbol table lookup/menu" } // CLEAR,LOAD,SAVE
|
{"SYMBASIC" , CmdSymbolsCommand , CMD_SYMBOLS_APPLESOFT , "Applesoft symbol table lookup/menu" }, // CLEAR,LOAD,SAVE
|
||||||
,{"SYMASM" , CmdSymbolsCommand , CMD_SYMBOLS_ASSEMBLY , "Assembly symbol table lookup/menu" } // CLEAR,LOAD,SAVE
|
{"SYMASM" , CmdSymbolsCommand , CMD_SYMBOLS_ASSEMBLY , "Assembly symbol table lookup/menu" }, // CLEAR,LOAD,SAVE
|
||||||
,{"SYMUSER" , CmdSymbolsCommand , CMD_SYMBOLS_USER_1 , "First user symbol table lookup/menu" } // CLEAR,LOAD,SAVE
|
{"SYMUSER" , CmdSymbolsCommand , CMD_SYMBOLS_USER_1 , "First user symbol table lookup/menu" }, // CLEAR,LOAD,SAVE
|
||||||
,{"SYMUSER2" , CmdSymbolsCommand , CMD_SYMBOLS_USER_2 , "Second User symbol table lookup/menu" } // CLEAR,LOAD,SAVE
|
{"SYMUSER2" , CmdSymbolsCommand , CMD_SYMBOLS_USER_2 , "Second User symbol table lookup/menu" }, // CLEAR,LOAD,SAVE
|
||||||
,{"SYMSRC" , CmdSymbolsCommand , CMD_SYMBOLS_SRC_1 , "First Source symbol table lookup/menu" } // CLEAR,LOAD,SAVE
|
{"SYMSRC" , CmdSymbolsCommand , CMD_SYMBOLS_SRC_1 , "First Source symbol table lookup/menu" }, // CLEAR,LOAD,SAVE
|
||||||
,{"SYMSRC2" , CmdSymbolsCommand , CMD_SYMBOLS_SRC_2 , "Second Source symbol table lookup/menu" } // CLEAR,LOAD,SAVE
|
{"SYMSRC2" , CmdSymbolsCommand , CMD_SYMBOLS_SRC_2 , "Second Source symbol table lookup/menu" }, // CLEAR,LOAD,SAVE
|
||||||
,{"SYMDOS33" , CmdSymbolsCommand , CMD_SYMBOLS_DOS33 , "DOS 3.3 symbol table lookup/menu" } // CLEAR,LOAD,SAVE
|
{"SYMDOS33" , CmdSymbolsCommand , CMD_SYMBOLS_DOS33 , "DOS 3.3 symbol table lookup/menu" }, // CLEAR,LOAD,SAVE
|
||||||
,{"SYMPRODOS" , CmdSymbolsCommand , CMD_SYMBOLS_PRODOS , "ProDOS symbol table lookup/menu" } // CLEAR,LOAD,SAVE
|
{"SYMPRODOS" , CmdSymbolsCommand , CMD_SYMBOLS_PRODOS , "ProDOS symbol table lookup/menu" }, // CLEAR,LOAD,SAVE
|
||||||
|
|
||||||
// ,{"SYMCLEAR" , CmdSymbolsClear , CMD_SYMBOLS_CLEAR } // can't use SC = SetCarry
|
// {TEXT("SYMCLEAR") , CmdSymbolsClear , CMD_SYMBOLS_CLEAR }, // can't use SC = SetCarry
|
||||||
,{"SYMINFO" , CmdSymbolsInfo , CMD_SYMBOLS_INFO , "Display summary of symbols" }
|
{TEXT("SYMINFO") , CmdSymbolsInfo , CMD_SYMBOLS_INFO , "Display summary of symbols" },
|
||||||
,{"SYMLIST" , CmdSymbolsList , CMD_SYMBOLS_LIST , "Lookup symbol in main/user/src tables" } // 'symbolname', can't use param '*'
|
{TEXT("SYMLIST") , CmdSymbolsList , CMD_SYMBOLS_LIST , "Lookup symbol in main/user/src tables" }, // 'symbolname', can't use param '*'
|
||||||
// Variables
|
// Variables
|
||||||
// ,{"CLEAR" , CmdVarsClear , CMD_VARIABLES_CLEAR }
|
// {TEXT("CLEAR") , CmdVarsClear , CMD_VARIABLES_CLEAR },
|
||||||
// ,{"VAR" , CmdVarsDefine , CMD_VARIABLES_DEFINE }
|
// {TEXT("VAR") , CmdVarsDefine , CMD_VARIABLES_DEFINE },
|
||||||
// ,{"INT8" , CmdVarsDefineInt8 , CMD_VARIABLES_DEFINE_INT8 }
|
// {TEXT("INT8") , CmdVarsDefineInt8 , CMD_VARIABLES_DEFINE_INT8},
|
||||||
// ,{"INT16" , CmdVarsDefineInt16 , CMD_VARIABLES_DEFINE_INT16 }
|
// {TEXT("INT16") , CmdVarsDefineInt16 , CMD_VARIABLES_DEFINE_INT16},
|
||||||
// ,{"VARS" , CmdVarsList , CMD_VARIABLES_LIST }
|
// {TEXT("VARS") , CmdVarsList , CMD_VARIABLES_LIST },
|
||||||
// ,{"VARSLOAD" , CmdVarsLoad , CMD_VARIABLES_LOAD }
|
// {TEXT("VARSLOAD") , CmdVarsLoad , CMD_VARIABLES_LOAD },
|
||||||
// ,{"VARSSAVE" , CmdVarsSave , CMD_VARIABLES_SAVE }
|
// {TEXT("VARSSAVE") , CmdVarsSave , CMD_VARIABLES_SAVE },
|
||||||
// ,{"SET" , CmdVarsSet , CMD_VARIABLES_SET }
|
// {TEXT("SET") , CmdVarsSet , CMD_VARIABLES_SET },
|
||||||
// View
|
// View
|
||||||
,{"TEXT" , CmdViewOutput_Text4X , CMD_VIEW_TEXT4X , "View Text screen (current page)" }
|
{TEXT("TEXT") , CmdViewOutput_Text4X , CMD_VIEW_TEXT4X, "View Text screen (current page)" },
|
||||||
,{"TEXT1" , CmdViewOutput_Text41 , CMD_VIEW_TEXT41 , "View Text screen Page 1" }
|
{TEXT("TEXT1") , CmdViewOutput_Text41 , CMD_VIEW_TEXT41, "View Text screen Page 1" },
|
||||||
,{"TEXT2" , CmdViewOutput_Text42 , CMD_VIEW_TEXT42 , "View Text screen Page 2" }
|
{TEXT("TEXT2") , CmdViewOutput_Text42 , CMD_VIEW_TEXT42, "View Text screen Page 2" },
|
||||||
,{"TEXT80" , CmdViewOutput_Text8X , CMD_VIEW_TEXT8X , "View 80-col Text screen (current page)" }
|
{TEXT("TEXT80") , CmdViewOutput_Text8X , CMD_VIEW_TEXT8X, "View 80-col Text screen (current page)" },
|
||||||
,{"TEXT81" , CmdViewOutput_Text81 , CMD_VIEW_TEXT81 , "View 80-col Text screen Page 1" }
|
{TEXT("TEXT81") , CmdViewOutput_Text81 , CMD_VIEW_TEXT81, "View 80-col Text screen Page 1" },
|
||||||
,{"TEXT82" , CmdViewOutput_Text82 , CMD_VIEW_TEXT82 , "View 80-col Text screen Page 2" }
|
{TEXT("TEXT82") , CmdViewOutput_Text82 , CMD_VIEW_TEXT82, "View 80-col Text screen Page 2" },
|
||||||
,{"GR" , CmdViewOutput_GRX , CMD_VIEW_GRX , "View Lo-Res screen (current page)" }
|
{TEXT("GR") , CmdViewOutput_GRX , CMD_VIEW_GRX , "View Lo-Res screen (current page)" },
|
||||||
,{"GR1" , CmdViewOutput_GR1 , CMD_VIEW_GR1 , "View Lo-Res screen Page 1" }
|
{TEXT("GR1") , CmdViewOutput_GR1 , CMD_VIEW_GR1 , "View Lo-Res screen Page 1" },
|
||||||
,{"GR2" , CmdViewOutput_GR2 , CMD_VIEW_GR2 , "View Lo-Res screen Page 2" }
|
{TEXT("GR2") , CmdViewOutput_GR2 , CMD_VIEW_GR2 , "View Lo-Res screen Page 2" },
|
||||||
,{"DGR" , CmdViewOutput_DGRX , CMD_VIEW_DGRX , "View Double lo-res (current page)" }
|
{TEXT("DGR") , CmdViewOutput_DGRX , CMD_VIEW_DGRX , "View Double lo-res (current page)" },
|
||||||
,{"DGR1" , CmdViewOutput_DGR1 , CMD_VIEW_DGR1 , "View Double lo-res Page 1" }
|
{TEXT("DGR1") , CmdViewOutput_DGR1 , CMD_VIEW_DGR1 , "View Double lo-res Page 1" },
|
||||||
,{"DGR2" , CmdViewOutput_DGR2 , CMD_VIEW_DGR2 , "View Double lo-res Page 2" }
|
{TEXT("DGR2") , CmdViewOutput_DGR2 , CMD_VIEW_DGR2 , "View Double lo-res Page 2" },
|
||||||
,{"HGR" , CmdViewOutput_HGRX , CMD_VIEW_HGRX , "View Hi-res (current page)" }
|
{TEXT("HGR") , CmdViewOutput_HGRX , CMD_VIEW_HGRX , "View Hi-res (current page)" },
|
||||||
,{"HGR1" , CmdViewOutput_HGR1 , CMD_VIEW_HGR1 , "View Hi-res Page 1" }
|
{TEXT("HGR1") , CmdViewOutput_HGR1 , CMD_VIEW_HGR1 , "View Hi-res Page 1" },
|
||||||
,{"HGR2" , CmdViewOutput_HGR2 , CMD_VIEW_HGR2 , "View Hi-res Page 2" }
|
{TEXT("HGR2") , CmdViewOutput_HGR2 , CMD_VIEW_HGR2 , "View Hi-res Page 2" },
|
||||||
,{"DHGR" , CmdViewOutput_DHGRX , CMD_VIEW_DHGRX , "View Double Hi-res (current page)" }
|
{TEXT("DHGR") , CmdViewOutput_DHGRX , CMD_VIEW_DHGRX , "View Double Hi-res (current page)" },
|
||||||
,{"DHGR1" , CmdViewOutput_DHGR1 , CMD_VIEW_DHGR1 , "View Double Hi-res Page 1" }
|
{TEXT("DHGR1") , CmdViewOutput_DHGR1 , CMD_VIEW_DHGR1 , "View Double Hi-res Page 1" },
|
||||||
,{"DHGR2" , CmdViewOutput_DHGR2 , CMD_VIEW_DHGR2 , "View Double Hi-res Page 2" }
|
{TEXT("DHGR2") , CmdViewOutput_DHGR2 , CMD_VIEW_DHGR2 , "View Double Hi-res Page 2" },
|
||||||
// Watch
|
// Watch
|
||||||
,{"W" , CmdWatch , CMD_WATCH , "Alias for WA (Watch Add)" }
|
{TEXT("W") , CmdWatch , CMD_WATCH , "Alias for WA (Watch Add)" },
|
||||||
,{"WA" , CmdWatchAdd , CMD_WATCH_ADD , "Add/Update address or symbol to watch" }
|
{TEXT("WA") , CmdWatchAdd , CMD_WATCH_ADD , "Add/Update address or symbol to watch" },
|
||||||
,{"WC" , CmdWatchClear , CMD_WATCH_CLEAR , "Clear (remove) watch" }
|
{TEXT("WC") , CmdWatchClear , CMD_WATCH_CLEAR , "Clear (remove) watch" },
|
||||||
,{"WD" , CmdWatchDisable , CMD_WATCH_DISABLE , "Disable specific watch - listed not active" }
|
{TEXT("WD") , CmdWatchDisable , CMD_WATCH_DISABLE , "Disable specific watch - it is still in the list, just not active" },
|
||||||
,{"WE" , CmdWatchEnable , CMD_WATCH_ENABLE , "(Re)Enable disabled watch" }
|
{TEXT("WE") , CmdWatchEnable , CMD_WATCH_ENABLE , "(Re)Enable disabled watch" },
|
||||||
,{"WL" , CmdWatchList , CMD_WATCH_LIST , "List all watches" }
|
{TEXT("WL") , CmdWatchList , CMD_WATCH_LIST , "List all watches" },
|
||||||
// ,{"WLOAD" , CmdWatchLoad , CMD_WATCH_LOAD , "Load Watches" } // Cant use as param to W
|
// {TEXT("WLOAD") , CmdWatchLoad , CMD_WATCH_LOAD , "Load Watches" }, // Cant use as param to W
|
||||||
,{"WSAVE" , CmdWatchSave , CMD_WATCH_SAVE , "Save Watches" } // due to symbol look-up
|
{TEXT("WSAVE") , CmdWatchSave , CMD_WATCH_SAVE , "Save Watches" }, // due to symbol look-up
|
||||||
// Window
|
// Window
|
||||||
,{"WIN" , CmdWindow , CMD_WINDOW , "Show specified debugger window" }
|
{TEXT("WIN") , CmdWindow , CMD_WINDOW , "Show specified debugger window" },
|
||||||
// CODE 0, CODE 1, CODE 2 ... ???
|
// CODE 0, CODE 1, CODE 2 ... ???
|
||||||
,{"CODE" , CmdWindowViewCode , CMD_WINDOW_CODE , "Switch to full code window" } // Can't use WC = WatchClear
|
{TEXT("CODE") , CmdWindowViewCode , CMD_WINDOW_CODE , "Switch to full code window" }, // Can't use WC = WatchClear
|
||||||
,{"CODE1" , CmdWindowShowCode1 , CMD_WINDOW_CODE_1 , "Show code on top split window" }
|
{TEXT("CODE1") , CmdWindowShowCode1 , CMD_WINDOW_CODE_1 , "Show code on top split window" },
|
||||||
,{"CODE2" , CmdWindowShowCode2 , CMD_WINDOW_CODE_2 , "Show code on bottom split window" }
|
{TEXT("CODE2") , CmdWindowShowCode2 , CMD_WINDOW_CODE_2 , "Show code on bottom split window" },
|
||||||
,{"CONSOLE" , CmdWindowViewConsole , CMD_WINDOW_CONSOLE , "Switch to full console window" }
|
{TEXT("CONSOLE") , CmdWindowViewConsole , CMD_WINDOW_CONSOLE , "Switch to full console window" },
|
||||||
,{"DATA" , CmdWindowViewData , CMD_WINDOW_DATA , "Switch to full data window" }
|
{TEXT("DATA") , CmdWindowViewData , CMD_WINDOW_DATA , "Switch to full data window" },
|
||||||
,{"DATA1" , CmdWindowShowData1 , CMD_WINDOW_DATA_1 , "Show data on top split window" }
|
{TEXT("DATA1") , CmdWindowShowData1 , CMD_WINDOW_DATA_1 , "Show data on top split window" },
|
||||||
,{"DATA2" , CmdWindowShowData2 , CMD_WINDOW_DATA_2 , "Show data on bottom split window" }
|
{TEXT("DATA2") , CmdWindowShowData2 , CMD_WINDOW_DATA_2 , "Show data on bottom split window" },
|
||||||
,{"SOURCE1" , CmdWindowShowSource1 , CMD_WINDOW_SOURCE_1 , "Show source on top split screen" }
|
{TEXT("SOURCE1") , CmdWindowShowSource1 , CMD_WINDOW_SOURCE_1, "Show source on top split screen" },
|
||||||
,{"SOURCE2" , CmdWindowShowSource2 , CMD_WINDOW_SOURCE_2 , "Show source on bottom split screen" }
|
{TEXT("SOURCE2") , CmdWindowShowSource2 , CMD_WINDOW_SOURCE_2, "Show source on bottom split screen" },
|
||||||
|
|
||||||
,{"\\" , CmdWindowViewOutput , CMD_WINDOW_OUTPUT , "Display Apple output until key pressed" }
|
{TEXT("\\") , CmdWindowViewOutput , CMD_WINDOW_OUTPUT , "Display Apple output until key pressed" },
|
||||||
// ,{"INFO" , CmdToggleInfoPanel , CMD_WINDOW_TOGGLE }
|
// {TEXT("INFO") , CmdToggleInfoPanel , CMD_WINDOW_TOGGLE },
|
||||||
// ,{"WINSOURCE" , CmdWindowShowSource , CMD_WINDOW_SOURCE }
|
// {TEXT("WINSOURCE") , CmdWindowShowSource , CMD_WINDOW_SOURCE },
|
||||||
// ,{"ZEROPAGE" , CmdWindowShowZeropage , CMD_WINDOW_ZEROPAGE }
|
// {TEXT("ZEROPAGE") , CmdWindowShowZeropage, CMD_WINDOW_ZEROPAGE },
|
||||||
// Zero Page
|
// Zero Page
|
||||||
,{"ZP" , CmdZeroPage , CMD_ZEROPAGE_POINTER , "Alias for ZPA (Zero Page Add)" }
|
{TEXT("ZP") , CmdZeroPage , CMD_ZEROPAGE_POINTER , "Alias for ZPA (Zero Page Add)" },
|
||||||
,{"ZP0" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_0 , "Set/Update/Remove ZP watch 0 " }
|
{TEXT("ZP0") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_0 , "Set/Update/Remove ZP watch 0 " },
|
||||||
,{"ZP1" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_1 , "Set/Update/Remove ZP watch 1" }
|
{TEXT("ZP1") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_1 , "Set/Update/Remove ZP watch 1" },
|
||||||
,{"ZP2" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_2 , "Set/Update/Remove ZP watch 2" }
|
{TEXT("ZP2") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_2 , "Set/Update/Remove ZP watch 2" },
|
||||||
,{"ZP3" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_3 , "Set/Update/Remove ZP watch 3" }
|
{TEXT("ZP3") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_3 , "Set/Update/Remove ZP watch 3" },
|
||||||
,{"ZP4" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_4 , "Set/Update/Remove ZP watch 4" }
|
{TEXT("ZP4") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_4 , "Set/Update/Remove ZP watch 4" },
|
||||||
,{"ZP5" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_5 , "Set/Update/Remove ZP watch 5 " }
|
{TEXT("ZP5") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_5 , "Set/Update/Remove ZP watch 5 " },
|
||||||
,{"ZP6" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_6 , "Set/Update/Remove ZP watch 6" }
|
{TEXT("ZP6") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_6 , "Set/Update/Remove ZP watch 6" },
|
||||||
,{"ZP7" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_7 , "Set/Update/Remove ZP watch 7" }
|
{TEXT("ZP7") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_7 , "Set/Update/Remove ZP watch 7" },
|
||||||
,{"ZPA" , CmdZeroPageAdd , CMD_ZEROPAGE_POINTER_ADD , "Add/Update address to zero page pointer" }
|
{TEXT("ZPA") , CmdZeroPageAdd , CMD_ZEROPAGE_POINTER_ADD , "Add/Update address to zero page pointer"},
|
||||||
,{"ZPC" , CmdZeroPageClear , CMD_ZEROPAGE_POINTER_CLEAR , "Clear (remove) zero page pointer" }
|
{TEXT("ZPC") , CmdZeroPageClear , CMD_ZEROPAGE_POINTER_CLEAR , "Clear (remove) zero page pointer" },
|
||||||
,{"ZPD" , CmdZeroPageDisable , CMD_ZEROPAGE_POINTER_DISABLE, "Disable zero page pointer" }
|
{TEXT("ZPD") , CmdZeroPageDisable , CMD_ZEROPAGE_POINTER_DISABLE,"Disable zero page pointer - it is still in the list, just not active" },
|
||||||
,{"ZPE" , CmdZeroPageEnable , CMD_ZEROPAGE_POINTER_ENABLE , "(Re)Enable disabled zero page pointer" }
|
{TEXT("ZPE") , CmdZeroPageEnable , CMD_ZEROPAGE_POINTER_ENABLE, "(Re)Enable disabled zero page pointer" },
|
||||||
,{"ZPL" , CmdZeroPageList , CMD_ZEROPAGE_POINTER_LIST , "List all zero page pointers" }
|
{TEXT("ZPL") , CmdZeroPageList , CMD_ZEROPAGE_POINTER_LIST , "List all zero page pointers" },
|
||||||
// ,{"ZPLOAD" , CmdZeroPageLoad , CMD_ZEROPAGE_POINTER_LOAD , "Load zero page pointers" } // Cant use as param to ZP
|
// {TEXT("ZPLOAD") , CmdZeroPageLoad , CMD_ZEROPAGE_POINTER_LOAD , "Load zero page pointers" }, // Cant use as param to ZP
|
||||||
,{"ZPSAVE" , CmdZeroPageSave , CMD_ZEROPAGE_POINTER_SAVE , "Save zero page pointers" } // due to symbol look-up
|
{TEXT("ZPSAVE") , CmdZeroPageSave , CMD_ZEROPAGE_POINTER_SAVE , "Save zero page pointers" }, // due to symbol look-up
|
||||||
|
|
||||||
// {"TIMEDEMO"),CmdTimeDemo, CMD_TIMEDEMO }, // CmdBenchmarkStart(), CmdBenchmarkStop()
|
// {TEXT("TIMEDEMO"),CmdTimeDemo, CMD_TIMEDEMO }, // CmdBenchmarkStart(), CmdBenchmarkStop()
|
||||||
// {"WC"),CmdShowCodeWindow}, // Can't use since WatchClear
|
// {TEXT("WC"),CmdShowCodeWindow}, // Can't use since WatchClear
|
||||||
// {"WD"),CmdShowDataWindow}, //
|
// {TEXT("WD"),CmdShowDataWindow}, //
|
||||||
|
|
||||||
// Internal Consistency Check
|
// Internal Consistency Check
|
||||||
,{ DEBUGGER__COMMANDS_VERIFY_TXT__, NULL, NUM_COMMANDS }
|
{ DEBUGGER__COMMANDS_VERIFY_TXT__, NULL, NUM_COMMANDS },
|
||||||
|
|
||||||
// Aliasies - Can be in any order
|
// Aliasies - Can be in any order
|
||||||
,{"->" , NULL , CMD_CURSOR_JUMP_PC }
|
{TEXT("->") , NULL , CMD_CURSOR_JUMP_PC },
|
||||||
,{"Ctrl ->" , NULL , CMD_CURSOR_SET_PC }
|
{TEXT("Ctrl ->" ) , NULL , CMD_CURSOR_SET_PC },
|
||||||
,{"Shift ->" , NULL , CMD_CURSOR_JUMP_PC } // at top
|
{TEXT("Shift ->") , NULL , CMD_CURSOR_JUMP_PC }, // at top
|
||||||
,{"INPUT" , CmdIn , CMD_IN }
|
{TEXT("INPUT") , CmdIn , CMD_IN },
|
||||||
// Data
|
// Data
|
||||||
// Flags - Clear
|
// Flags - Clear
|
||||||
,{"RC" , CmdFlagClear , CMD_FLAG_CLR_C , "Clear Flag Carry" } // 0 // Legacy
|
{TEXT("RC") , CmdFlagClear , CMD_FLAG_CLR_C , "Clear Flag Carry" }, // 0 // Legacy
|
||||||
,{"RZ" , CmdFlagClear , CMD_FLAG_CLR_Z , "Clear Flag Zero" } // 1
|
{TEXT("RZ") , CmdFlagClear , CMD_FLAG_CLR_Z , "Clear Flag Zero" }, // 1
|
||||||
,{"RI" , CmdFlagClear , CMD_FLAG_CLR_I , "Clear Flag Interrupts Disabled" } // 2
|
{TEXT("RI") , CmdFlagClear , CMD_FLAG_CLR_I , "Clear Flag Interrupts Disabled" }, // 2
|
||||||
,{"RD" , CmdFlagClear , CMD_FLAG_CLR_D , "Clear Flag Decimal (BCD)" } // 3
|
{TEXT("RD") , CmdFlagClear , CMD_FLAG_CLR_D , "Clear Flag Decimal (BCD)" }, // 3
|
||||||
,{"RB" , CmdFlagClear , CMD_FLAG_CLR_B , "CLear Flag Break" } // 4 // Legacy
|
{TEXT("RB") , CmdFlagClear , CMD_FLAG_CLR_B , "CLear Flag Break" }, // 4 // Legacy
|
||||||
,{"RR" , CmdFlagClear , CMD_FLAG_CLR_R , "Clear Flag Reserved" } // 5
|
{TEXT("RR") , CmdFlagClear , CMD_FLAG_CLR_R , "Clear Flag Reserved" }, // 5
|
||||||
,{"RV" , CmdFlagClear , CMD_FLAG_CLR_V , "Clear Flag Overflow" } // 6
|
{TEXT("RV") , CmdFlagClear , CMD_FLAG_CLR_V , "Clear Flag Overflow" }, // 6
|
||||||
,{"RN" , CmdFlagClear , CMD_FLAG_CLR_N , "Clear Flag Negative (Sign)" } // 7
|
{TEXT("RN") , CmdFlagClear , CMD_FLAG_CLR_N , "Clear Flag Negative (Sign)" }, // 7
|
||||||
// Flags - Set
|
// Flags - Set
|
||||||
,{"SC" , CmdFlagSet , CMD_FLAG_SET_C , "Set Flag Carry" } // 0
|
{TEXT("SC") , CmdFlagSet , CMD_FLAG_SET_C , "Set Flag Carry" }, // 0
|
||||||
,{"SZ" , CmdFlagSet , CMD_FLAG_SET_Z , "Set Flag Zero" } // 1
|
{TEXT("SZ") , CmdFlagSet , CMD_FLAG_SET_Z , "Set Flag Zero" }, // 1
|
||||||
,{"SI" , CmdFlagSet , CMD_FLAG_SET_I , "Set Flag Interrupts Disabled" } // 2
|
{TEXT("SI") , CmdFlagSet , CMD_FLAG_SET_I , "Set Flag Interrupts Disabled" }, // 2
|
||||||
,{"SD" , CmdFlagSet , CMD_FLAG_SET_D , "Set Flag Decimal (BCD)" } // 3
|
{TEXT("SD") , CmdFlagSet , CMD_FLAG_SET_D , "Set Flag Decimal (BCD)" }, // 3
|
||||||
,{"SB" , CmdFlagSet , CMD_FLAG_SET_B , "CLear Flag Break" } // 4 // Legacy
|
{TEXT("SB") , CmdFlagSet , CMD_FLAG_SET_B , "CLear Flag Break" }, // 4 // Legacy
|
||||||
,{"SR" , CmdFlagSet , CMD_FLAG_SET_R , "Clear Flag Reserved" } // 5
|
{TEXT("SR") , CmdFlagSet , CMD_FLAG_SET_R , "Clear Flag Reserved" }, // 5
|
||||||
,{"SV" , CmdFlagSet , CMD_FLAG_SET_V , "Clear Flag Overflow" } // 6
|
{TEXT("SV") , CmdFlagSet , CMD_FLAG_SET_V , "Clear Flag Overflow" }, // 6
|
||||||
,{"SN" , CmdFlagSet , CMD_FLAG_SET_N , "Clear Flag Negative" } // 7
|
{TEXT("SN") , CmdFlagSet , CMD_FLAG_SET_N , "Clear Flag Negative" }, // 7
|
||||||
// Memory
|
// Memory
|
||||||
,{"D" , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 , "Hex dump in the mini memory area 1" } // FIXME: Must also work in DATA screen
|
{TEXT("D") , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 , "Hex dump in the mini memory area 1" }, // FIXME: Must also work in DATA screen
|
||||||
,{"M1" , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 } // alias
|
{TEXT("M1") , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 }, // alias
|
||||||
,{"M2" , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_2 } // alias
|
{TEXT("M2") , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_2 }, // alias
|
||||||
|
|
||||||
,{"ME8" , CmdMemoryEnterByte , CMD_MEMORY_ENTER_BYTE } // changed from EB -- bugfix: EB:## ##
|
{TEXT("ME8") , CmdMemoryEnterByte , CMD_MEMORY_ENTER_BYTE }, // changed from EB -- bugfix: EB:## ##
|
||||||
,{"ME16" , CmdMemoryEnterWord , CMD_MEMORY_ENTER_WORD }
|
{TEXT("ME16") , CmdMemoryEnterWord , CMD_MEMORY_ENTER_WORD },
|
||||||
,{"MM" , CmdMemoryMove , CMD_MEMORY_MOVE }
|
{TEXT("MM") , CmdMemoryMove , CMD_MEMORY_MOVE },
|
||||||
,{"MS" , CmdMemorySearch , CMD_MEMORY_SEARCH } // CmdMemorySearch
|
{TEXT("MS") , CmdMemorySearch , CMD_MEMORY_SEARCH }, // CmdMemorySearch
|
||||||
,{"P0" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_0 }
|
{TEXT("P0") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_0 },
|
||||||
,{"P1" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_1 }
|
{TEXT("P1") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_1 },
|
||||||
,{"P2" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_2 }
|
{TEXT("P2") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_2 },
|
||||||
,{"P3" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_3 }
|
{TEXT("P3") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_3 },
|
||||||
,{"P4" , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_4 }
|
{TEXT("P4") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_4 },
|
||||||
,{"REGISTER" , CmdRegisterSet , CMD_REGISTER_SET }
|
{TEXT("REGISTER") , CmdRegisterSet , CMD_REGISTER_SET },
|
||||||
// ,{"RET" , CmdStackReturn , CMD_STACK_RETURN }
|
// {TEXT("RET") , CmdStackReturn , CMD_STACK_RETURN },
|
||||||
,{"TRACE" , CmdTrace , CMD_TRACE }
|
{TEXT("TRACE") , CmdTrace , CMD_TRACE },
|
||||||
|
|
||||||
// ,{"SYMBOLS" , CmdSymbols , CMD_SYMBOLS_LOOKUP , "Return " }
|
// {TEXT("SYMBOLS") , CmdSymbols , CMD_SYMBOLS_LOOKUP , "Return " },
|
||||||
// ,{"SYMBOLS1" , CmdSymbolsInfo , CMD_SYMBOLS_1 }
|
// {TEXT("SYMBOLS1") , CmdSymbolsInfo , CMD_SYMBOLS_1 },
|
||||||
// ,{"SYMBOLS2" , CmdSymbolsInfo , CMD_SYMBOLS_2 }
|
// {TEXT("SYMBOLS2") , CmdSymbolsInfo , CMD_SYMBOLS_2 },
|
||||||
// ,{"SYM0" , CmdSymbolsInfo , CMD_SYMBOLS_ROM }
|
// {"SYM0" , CmdSymbolsInfo , CMD_SYMBOLS_ROM },
|
||||||
// ,{"SYM1" , CmdSymbolsInfo , CMD_SYMBOLS_APPLESOFT }
|
// {"SYM1" , CmdSymbolsInfo , CMD_SYMBOLS_APPLESOFT },
|
||||||
// ,{"SYM2" , CmdSymbolsInfo , CMD_SYMBOLS_ASSEMBLY }
|
// {"SYM2" , CmdSymbolsInfo , CMD_SYMBOLS_ASSEMBLY },
|
||||||
// ,{"SYM3" , CmdSymbolsInfo , CMD_SYMBOLS_USER_1 }
|
// {"SYM3" , CmdSymbolsInfo , CMD_SYMBOLS_USER_1 },
|
||||||
// ,{"SYM4" , CmdSymbolsInfo , CMD_SYMBOLS_USER_2 }
|
// {"SYM4" , CmdSymbolsInfo , CMD_SYMBOLS_USER_2 },
|
||||||
// ,{"SYM5" , CmdSymbolsInfo , CMD_SYMBOLS_SRC_1 }
|
// {"SYM5" , CmdSymbolsInfo , CMD_SYMBOLS_SRC_1 },
|
||||||
// ,{"SYM6" , CmdSymbolsInfo , CMD_SYMBOLS_SRC_2 }
|
// {"SYM6" , CmdSymbolsInfo , CMD_SYMBOLS_SRC_2 },
|
||||||
,{"SYMDOS" , CmdSymbolsCommand , CMD_SYMBOLS_DOS33 }
|
{"SYMDOS" , CmdSymbolsCommand , CMD_SYMBOLS_DOS33 },
|
||||||
,{"SYMPRO" , CmdSymbolsCommand , CMD_SYMBOLS_PRODOS }
|
{"SYMPRO" , CmdSymbolsCommand , CMD_SYMBOLS_PRODOS },
|
||||||
|
|
||||||
,{"TEXT40" , CmdViewOutput_Text4X , CMD_VIEW_TEXT4X }
|
{TEXT("TEXT40") , CmdViewOutput_Text4X , CMD_VIEW_TEXT4X },
|
||||||
,{"TEXT41" , CmdViewOutput_Text41 , CMD_VIEW_TEXT41 }
|
{TEXT("TEXT41") , CmdViewOutput_Text41 , CMD_VIEW_TEXT41 },
|
||||||
,{"TEXT42" , CmdViewOutput_Text42 , CMD_VIEW_TEXT42 }
|
{TEXT("TEXT42") , CmdViewOutput_Text42 , CMD_VIEW_TEXT42 },
|
||||||
|
|
||||||
// ,{"WATCH" , CmdWatchAdd , CMD_WATCH_ADD }
|
// {TEXT("WATCH") , CmdWatchAdd , CMD_WATCH_ADD },
|
||||||
,{"WINDOW" , CmdWindow , CMD_WINDOW }
|
{TEXT("WINDOW") , CmdWindow , CMD_WINDOW },
|
||||||
// ,{"W?" , CmdWatchAdd , CMD_WATCH_ADD }
|
// {TEXT("W?") , CmdWatchAdd , CMD_WATCH_ADD },
|
||||||
,{"ZAP" , CmdNOP , CMD_NOP }
|
{TEXT("ZAP") , CmdNOP , CMD_NOP },
|
||||||
|
|
||||||
// DEPRECATED -- Probably should be removed in a future version
|
// DEPRECATED -- Probably should be removed in a future version
|
||||||
,{"BENCH" , CmdBenchmarkStart , CMD_BENCHMARK } // already hae BENCHMARK
|
{TEXT("BENCH") , CmdBenchmarkStart , CMD_BENCHMARK },
|
||||||
,{"EXITBENCH" , NULL , CMD_BENCHMARK } // 2.8.03 was incorrectly alias with 'E' Bug #246. // CmdBenchmarkStop
|
{TEXT("EXITBENCH") , NULL , CMD_BENCHMARK }, // 2.8.03 was incorrectly alias with 'E' Bug #246. // CmdBenchmarkStop
|
||||||
,{"MDB" , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 } // MemoryDumpByte // Did anyone actually use this??
|
{TEXT("MDB") , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 }, // MemoryDumpByte // Did anyone actually use this??
|
||||||
// ,{"MEMORY" , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 } // MemoryDumpByte // Did anyone actually use this??
|
// {TEXT("MEMORY") , CmdMemoryMiniDumpHex , CMD_MEM_MINI_DUMP_HEX_1 }, // MemoryDumpByte // Did anyone actually use this??
|
||||||
};
|
};
|
||||||
|
|
||||||
const int NUM_COMMANDS_WITH_ALIASES = sizeof(g_aCommands) / sizeof (Command_t); // Determined at compile-time ;-)
|
const int NUM_COMMANDS_WITH_ALIASES = sizeof(g_aCommands) / sizeof (Command_t); // Determined at compile-time ;-)
|
||||||
|
@ -391,114 +391,113 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
Command_t g_aParameters[] =
|
Command_t g_aParameters[] =
|
||||||
{
|
{
|
||||||
// Breakpoint
|
// Breakpoint
|
||||||
{"<=" , NULL, PARAM_BP_LESS_EQUAL }
|
{TEXT("<=") , NULL, PARAM_BP_LESS_EQUAL },
|
||||||
,{"<" , NULL, PARAM_BP_LESS_THAN }
|
{TEXT("<" ) , NULL, PARAM_BP_LESS_THAN },
|
||||||
,{"=" , NULL, PARAM_BP_EQUAL }
|
{TEXT("=" ) , NULL, PARAM_BP_EQUAL },
|
||||||
,{"!=" , NULL, PARAM_BP_NOT_EQUAL }
|
{TEXT("!=") , NULL, PARAM_BP_NOT_EQUAL },
|
||||||
,{"!" , NULL, PARAM_BP_NOT_EQUAL_1 }
|
{TEXT("!" ) , NULL, PARAM_BP_NOT_EQUAL_1 },
|
||||||
,{">" , NULL, PARAM_BP_GREATER_THAN }
|
{TEXT(">" ) , NULL, PARAM_BP_GREATER_THAN },
|
||||||
,{">=" , NULL, PARAM_BP_GREATER_EQUAL }
|
{TEXT(">=") , NULL, PARAM_BP_GREATER_EQUAL },
|
||||||
,{"R" , NULL, PARAM_BP_READ }
|
{TEXT("R") , NULL, PARAM_BP_READ },
|
||||||
,{"?" , NULL, PARAM_BP_READ }
|
{TEXT("?") , NULL, PARAM_BP_READ },
|
||||||
,{"W" , NULL, PARAM_BP_WRITE }
|
{TEXT("W") , NULL, PARAM_BP_WRITE },
|
||||||
,{"@" , NULL, PARAM_BP_WRITE }
|
{TEXT("@") , NULL, PARAM_BP_WRITE },
|
||||||
,{"*" , NULL, PARAM_BP_READ_WRITE }
|
{TEXT("*") , NULL, PARAM_BP_READ_WRITE },
|
||||||
// Regs (for PUSH / POP)
|
// Regs (for PUSH / POP)
|
||||||
,{"A" , NULL, PARAM_REG_A }
|
{TEXT("A") , NULL, PARAM_REG_A },
|
||||||
,{"X" , NULL, PARAM_REG_X }
|
{TEXT("X") , NULL, PARAM_REG_X },
|
||||||
,{"Y" , NULL, PARAM_REG_Y }
|
{TEXT("Y") , NULL, PARAM_REG_Y },
|
||||||
,{"PC" , NULL, PARAM_REG_PC }
|
{TEXT("PC") , NULL, PARAM_REG_PC },
|
||||||
,{"S" , NULL, PARAM_REG_SP }
|
{TEXT("S") , NULL, PARAM_REG_SP },
|
||||||
// ,{"G" , NULL, PARAM_REG_PC }
|
|
||||||
// Flags
|
// Flags
|
||||||
,{"P" , NULL, PARAM_FLAGS }
|
{TEXT("P") , NULL, PARAM_FLAGS },
|
||||||
,{"C" , NULL, PARAM_FLAG_C } // ---- ---1 Carry
|
{TEXT("C") , NULL, PARAM_FLAG_C }, // ---- ---1 Carry
|
||||||
,{"Z" , NULL, PARAM_FLAG_Z } // ---- --1- Zero
|
{TEXT("Z") , NULL, PARAM_FLAG_Z }, // ---- --1- Zero
|
||||||
,{"I" , NULL, PARAM_FLAG_I } // ---- -1-- Interrupt
|
{TEXT("I") , NULL, PARAM_FLAG_I }, // ---- -1-- Interrupt
|
||||||
,{"D" , NULL, PARAM_FLAG_D } // ---- 1--- Decimal
|
{TEXT("D") , NULL, PARAM_FLAG_D }, // ---- 1--- Decimal
|
||||||
,{"B" , NULL, PARAM_FLAG_B } // ---1 ---- Break
|
{TEXT("B") , NULL, PARAM_FLAG_B }, // ---1 ---- Break
|
||||||
,{"R" , NULL, PARAM_FLAG_R } // --1- ---- Reserved
|
{TEXT("R") , NULL, PARAM_FLAG_R }, // --1- ---- Reserved
|
||||||
,{"V" , NULL, PARAM_FLAG_V } // -1-- ---- Overflow
|
{TEXT("V") , NULL, PARAM_FLAG_V }, // -1-- ---- Overflow
|
||||||
,{"N" , NULL, PARAM_FLAG_N } // 1--- ---- Sign
|
{TEXT("N") , NULL, PARAM_FLAG_N }, // 1--- ---- Sign
|
||||||
// Disasm
|
// Disasm
|
||||||
,{"BRANCH" , NULL, PARAM_CONFIG_BRANCH }
|
{TEXT("BRANCH") , NULL, PARAM_CONFIG_BRANCH },
|
||||||
,{"COLON" , NULL, PARAM_CONFIG_COLON }
|
{TEXT("COLON") , NULL, PARAM_CONFIG_COLON },
|
||||||
,{"OPCODE" , NULL, PARAM_CONFIG_OPCODE }
|
{TEXT("OPCODE") , NULL, PARAM_CONFIG_OPCODE },
|
||||||
,{"POINTER" , NULL, PARAM_CONFIG_POINTER }
|
{TEXT("POINTER") , NULL, PARAM_CONFIG_POINTER },
|
||||||
,{"SPACES" , NULL, PARAM_CONFIG_SPACES }
|
{TEXT("SPACES") , NULL, PARAM_CONFIG_SPACES },
|
||||||
,{"TARGET" , NULL, PARAM_CONFIG_TARGET }
|
{TEXT("TARGET") , NULL, PARAM_CONFIG_TARGET },
|
||||||
// Disk
|
// Disk
|
||||||
,{"EJECT" , NULL, PARAM_DISK_EJECT }
|
{TEXT("EJECT") , NULL, PARAM_DISK_EJECT },
|
||||||
,{"INFO" , NULL, PARAM_DISK_INFO }
|
{TEXT("INFO") , NULL, PARAM_DISK_INFO },
|
||||||
,{"PROTECT" , NULL, PARAM_DISK_PROTECT }
|
{TEXT("PROTECT") , NULL, PARAM_DISK_PROTECT },
|
||||||
,{"READ" , NULL, PARAM_DISK_READ }
|
{TEXT("READ") , NULL, PARAM_DISK_READ },
|
||||||
// Font (Config)
|
// Font (Config)
|
||||||
,{"MODE" , NULL, PARAM_FONT_MODE } // also INFO, CONSOLE, DISASM (from Window)
|
{TEXT("MODE") , NULL, PARAM_FONT_MODE }, // also INFO, CONSOLE, DISASM (from Window)
|
||||||
// General
|
// General
|
||||||
,{"FIND" , NULL, PARAM_FIND }
|
{TEXT("FIND") , NULL, PARAM_FIND },
|
||||||
,{"BRANCH" , NULL, PARAM_BRANCH }
|
{TEXT("BRANCH") , NULL, PARAM_BRANCH },
|
||||||
,{"CATEGORY" , NULL, PARAM_CATEGORY }
|
{"CATEGORY" , NULL, PARAM_CATEGORY },
|
||||||
,{"CLEAR" , NULL, PARAM_CLEAR }
|
{TEXT("CLEAR") , NULL, PARAM_CLEAR },
|
||||||
,{"LOAD" , NULL, PARAM_LOAD }
|
{TEXT("LOAD") , NULL, PARAM_LOAD },
|
||||||
,{"LIST" , NULL, PARAM_LIST }
|
{TEXT("LIST") , NULL, PARAM_LIST },
|
||||||
,{"OFF" , NULL, PARAM_OFF }
|
{TEXT("OFF") , NULL, PARAM_OFF },
|
||||||
,{"ON" , NULL, PARAM_ON }
|
{TEXT("ON") , NULL, PARAM_ON },
|
||||||
,{"RESET" , NULL, PARAM_RESET }
|
{TEXT("RESET") , NULL, PARAM_RESET },
|
||||||
,{"SAVE" , NULL, PARAM_SAVE }
|
{TEXT("SAVE") , NULL, PARAM_SAVE },
|
||||||
,{"START" , NULL, PARAM_START } // benchmark
|
{TEXT("START") , NULL, PARAM_START }, // benchmark
|
||||||
,{"STOP" , NULL, PARAM_STOP } // benchmark
|
{TEXT("STOP") , NULL, PARAM_STOP }, // benchmark
|
||||||
// Help Categories
|
// Help Categories
|
||||||
,{"*" , NULL, PARAM_WILDSTAR }
|
{"*" , NULL, PARAM_WILDSTAR },
|
||||||
,{"BOOKMARKS" , NULL, PARAM_CAT_BOOKMARKS }
|
{"BOOKMARKS" , NULL, PARAM_CAT_BOOKMARKS },
|
||||||
,{"BREAKPOINTS", NULL, PARAM_CAT_BREAKPOINTS }
|
{"BREAKPOINTS" , NULL, PARAM_CAT_BREAKPOINTS },
|
||||||
,{"CONFIG" , NULL, PARAM_CAT_CONFIG }
|
{"CONFIG" , NULL, PARAM_CAT_CONFIG },
|
||||||
,{"CPU" , NULL, PARAM_CAT_CPU }
|
{"CPU" , NULL, PARAM_CAT_CPU },
|
||||||
// ,{"EXPRESSION" ,
|
// {TEXT("EXPRESSION") ,
|
||||||
,{"FLAGS" , NULL, PARAM_CAT_FLAGS }
|
{"FLAGS" , NULL, PARAM_CAT_FLAGS },
|
||||||
,{"HELP" , NULL, PARAM_CAT_HELP }
|
{"HELP" , NULL, PARAM_CAT_HELP },
|
||||||
,{"KEYBOARD" , NULL, PARAM_CAT_KEYBOARD }
|
{"KEYBOARD" , NULL, PARAM_CAT_KEYBOARD },
|
||||||
,{"MEMORY" , NULL, PARAM_CAT_MEMORY } // alias // SOURCE [SYMBOLS] [MEMORY] filename
|
{"MEMORY" , NULL, PARAM_CAT_MEMORY }, // alias // SOURCE [SYMBOLS] [MEMORY] filename
|
||||||
,{"OUTPUT" , NULL, PARAM_CAT_OUTPUT }
|
{"OUTPUT" , NULL, PARAM_CAT_OUTPUT },
|
||||||
,{"OPERATORS" , NULL, PARAM_CAT_OPERATORS }
|
{"OPERATORS" , NULL, PARAM_CAT_OPERATORS },
|
||||||
,{"RANGE" , NULL, PARAM_CAT_RANGE }
|
{"RANGE" , NULL, PARAM_CAT_RANGE },
|
||||||
// ,{"REGISTERS" NULL, PARAM_CAT_REGISTERS }
|
// {TEXT("REGISTERS") , NULL, PARAM_CAT_REGISTERS },
|
||||||
,{"SYMBOLS" , NULL, PARAM_CAT_SYMBOLS }
|
{"SYMBOLS" , NULL, PARAM_CAT_SYMBOLS },
|
||||||
,{"VIEW" , NULL, PARAM_CAT_VIEW }
|
{"VIEW" , NULL, PARAM_CAT_VIEW },
|
||||||
,{"WATCHES" , NULL, PARAM_CAT_WATCHES }
|
{"WATCHES" , NULL, PARAM_CAT_WATCHES },
|
||||||
,{"WINDOW" , NULL, PARAM_CAT_WINDOW }
|
{"WINDOW" , NULL, PARAM_CAT_WINDOW },
|
||||||
,{"ZEROPAGE" , NULL, PARAM_CAT_ZEROPAGE }
|
{"ZEROPAGE" , NULL, PARAM_CAT_ZEROPAGE },
|
||||||
// Memory
|
// Memory
|
||||||
,{"?" , NULL, PARAM_MEM_SEARCH_WILD }
|
{TEXT("?") , NULL, PARAM_MEM_SEARCH_WILD },
|
||||||
// ,{"*" , NULL, PARAM_MEM_SEARCH_BYTE }
|
// {TEXT("*") , NULL, PARAM_MEM_SEARCH_BYTE },
|
||||||
// Source level debugging
|
// Source level debugging
|
||||||
,{"MEM" , NULL, PARAM_SRC_MEMORY }
|
{TEXT("MEM") , NULL, PARAM_SRC_MEMORY },
|
||||||
,{"MEMORY" , NULL, PARAM_SRC_MEMORY }
|
{TEXT("MEMORY") , NULL, PARAM_SRC_MEMORY },
|
||||||
,{"SYM" , NULL, PARAM_SRC_SYMBOLS }
|
{TEXT("SYM") , NULL, PARAM_SRC_SYMBOLS },
|
||||||
,{"SYMBOLS" , NULL, PARAM_SRC_SYMBOLS }
|
{TEXT("SYMBOLS") , NULL, PARAM_SRC_SYMBOLS },
|
||||||
,{"MERLIN" , NULL, PARAM_SRC_MERLIN }
|
{TEXT("MERLIN") , NULL, PARAM_SRC_MERLIN },
|
||||||
,{"ORCA" , NULL, PARAM_SRC_ORCA }
|
{TEXT("ORCA") , NULL, PARAM_SRC_ORCA },
|
||||||
// View
|
// View
|
||||||
// ,{"VIEW") , NULL, PARAM_SRC_??? },
|
// {TEXT("VIEW") , NULL, PARAM_SRC_??? },
|
||||||
// Window Win Cmd WinEffects CmdEffects
|
// Window Win Cmd WinEffects CmdEffects
|
||||||
,{"CODE" , NULL, PARAM_CODE } // x x code win only switch to code window
|
{TEXT("CODE") , NULL, PARAM_CODE }, // x x code win only switch to code window
|
||||||
// ,{"CODE1" , NULL, PARAM_CODE_1 } // - x code/data win
|
// {TEXT("CODE1") , NULL, PARAM_CODE_1 }, // - x code/data win
|
||||||
,{"CODE2" , NULL, PARAM_CODE_2 } // - x code/data win
|
{TEXT("CODE2") , NULL, PARAM_CODE_2 }, // - x code/data win
|
||||||
,{"CONSOLE" , NULL, PARAM_CONSOLE } // x - switch to console window
|
{TEXT("CONSOLE") , NULL, PARAM_CONSOLE }, // x - switch to console window
|
||||||
,{"DATA" , NULL, PARAM_DATA } // x x data win only switch to data window
|
{TEXT("DATA") , NULL, PARAM_DATA }, // x x data win only switch to data window
|
||||||
// ,{"DATA1" , NULL, PARAM_DATA_1 } // - x code/data win
|
// {TEXT("DATA1") , NULL, PARAM_DATA_1 }, // - x code/data win
|
||||||
,{"DATA2" , NULL, PARAM_DATA_2 } // - x code/data win
|
{TEXT("DATA2") , NULL, PARAM_DATA_2 }, // - x code/data win
|
||||||
,{"DISASM" , NULL, PARAM_DISASM } //
|
{TEXT("DISASM") , NULL, PARAM_DISASM }, //
|
||||||
,{"INFO" , NULL, PARAM_INFO } // - x code/data Toggles showing/hiding Regs/Stack/BP/Watches/ZP
|
{TEXT("INFO") , NULL, PARAM_INFO }, // - x code/data Toggles showing/hiding Regs/Stack/BP/Watches/ZP
|
||||||
,{"SOURCE" , NULL, PARAM_SOURCE } // x x switch to source window
|
{TEXT("SOURCE") , NULL, PARAM_SOURCE }, // x x switch to source window
|
||||||
,{"SRC" , NULL, PARAM_SOURCE } // alias
|
{TEXT("SRC") , NULL, PARAM_SOURCE }, // alias
|
||||||
// ,{"SOURCE_1" , NULL, PARAM_SOURCE_1 } // - x code/data
|
// {TEXT("SOURCE_1") , NULL, PARAM_SOURCE_1 }, // - x code/data
|
||||||
,{"SOURCE2 " , NULL, PARAM_SOURCE_2 } // - x
|
{TEXT("SOURCE2 ") , NULL, PARAM_SOURCE_2 }, // - x
|
||||||
,{"SYMBOLS" , NULL, PARAM_SYMBOLS } // x x code/data win switch to symbols window
|
{TEXT("SYMBOLS") , NULL, PARAM_SYMBOLS }, // x x code/data win switch to symbols window
|
||||||
,{"SYM" , NULL, PARAM_SYMBOLS } // alias x SOURCE [SYM] [MEM] filename
|
{TEXT("SYM") , NULL, PARAM_SYMBOLS }, // alias x SOURCE [SYM] [MEM] filename
|
||||||
// ,{"SYMBOL1" , NULL, PARAM_SYMBOL_1 } // - x code/data win
|
// {TEXT("SYMBOL1") , NULL, PARAM_SYMBOL_1 }, // - x code/data win
|
||||||
,{"SYMBOL2" , NULL, PARAM_SYMBOL_2 } // - x code/data win
|
{TEXT("SYMBOL2") , NULL, PARAM_SYMBOL_2 }, // - x code/data win
|
||||||
// Internal Consistency Check
|
// Internal Consistency Check
|
||||||
,{DEBUGGER__PARAMS_VERIFY_TXT__,NULL,NUM_PARAMS}
|
{ DEBUGGER__PARAMS_VERIFY_TXT__, NULL, NUM_PARAMS },
|
||||||
};
|
};
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -512,7 +511,7 @@ void VerifyDebuggerCommandTable()
|
||||||
if ( g_aCommands[ iCmd ].iCommand != iCmd)
|
if ( g_aCommands[ iCmd ].iCommand != iCmd)
|
||||||
{
|
{
|
||||||
sprintf( sText, "*** ERROR *** Enumerated Commands mis-matched at #%d!", iCmd );
|
sprintf( sText, "*** ERROR *** Enumerated Commands mis-matched at #%d!", iCmd );
|
||||||
MessageBoxA( g_hFrameWindow, sText, "ERROR", MB_OK );
|
MessageBoxA( g_hFrameWindow, sText, TEXT("ERROR"), MB_OK );
|
||||||
PostQuitMessage( 1 );
|
PostQuitMessage( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -521,14 +520,14 @@ void VerifyDebuggerCommandTable()
|
||||||
if (strcmp( g_aCommands[ NUM_COMMANDS ].m_sName, DEBUGGER__COMMANDS_VERIFY_TXT__))
|
if (strcmp( g_aCommands[ NUM_COMMANDS ].m_sName, DEBUGGER__COMMANDS_VERIFY_TXT__))
|
||||||
{
|
{
|
||||||
sprintf( sText, "*** ERROR *** Total Commands mis-matched!" );
|
sprintf( sText, "*** ERROR *** Total Commands mis-matched!" );
|
||||||
MessageBoxA( g_hFrameWindow, sText, "ERROR", MB_OK );
|
MessageBoxA( g_hFrameWindow, sText, TEXT("ERROR"), MB_OK );
|
||||||
PostQuitMessage( 1 );
|
PostQuitMessage( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp( g_aParameters[ NUM_PARAMS ].m_sName, DEBUGGER__PARAMS_VERIFY_TXT__))
|
if (strcmp( g_aParameters[ NUM_PARAMS ].m_sName, DEBUGGER__PARAMS_VERIFY_TXT__))
|
||||||
{
|
{
|
||||||
sprintf( sText, "*** ERROR *** Total Parameters mis-matched!" );
|
sprintf( sText, "*** ERROR *** Total Parameters mis-matched!" );
|
||||||
MessageBoxA( g_hFrameWindow, sText, "ERROR", MB_OK );
|
MessageBoxA( g_hFrameWindow, sText, TEXT("ERROR"), MB_OK );
|
||||||
PostQuitMessage( 2 );
|
PostQuitMessage( 2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,8 +279,9 @@ bool ConsoleBufferPush ( const char * pText )
|
||||||
const char *pSrc = pText;
|
const char *pSrc = pText;
|
||||||
conchar_t *pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
|
conchar_t *pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
|
||||||
|
|
||||||
while ((x < CONSOLE_WIDTH) && (c = *pSrc))
|
while ((x < CONSOLE_WIDTH) && *pSrc)
|
||||||
{
|
{
|
||||||
|
c = *pSrc;
|
||||||
if ((c == '\n') || (x == (CONSOLE_WIDTH - 1)))
|
if ((c == '\n') || (x == (CONSOLE_WIDTH - 1)))
|
||||||
{
|
{
|
||||||
*pDst = 0;
|
*pDst = 0;
|
||||||
|
|
|
@ -1223,7 +1223,7 @@ void DrawBreakpoints ( int line )
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
int GetConsoleLineHeightPixels()
|
int GetConsoleLineHeightPixels()
|
||||||
{
|
{
|
||||||
int nHeight = nHeight = g_aFontConfig[ FONT_CONSOLE ]._nFontHeight; // _nLineHeight; // _nFontHeight;
|
int nHeight = g_aFontConfig[ FONT_CONSOLE ]._nFontHeight; // _nLineHeight; // _nFontHeight;
|
||||||
/*
|
/*
|
||||||
if (g_iFontSpacing == FONT_SPACING_CLASSIC)
|
if (g_iFontSpacing == FONT_SPACING_CLASSIC)
|
||||||
{
|
{
|
||||||
|
@ -2434,10 +2434,10 @@ void DrawMemory ( int line, int iMemDump )
|
||||||
DEVICE_e eDevice = pMD->eDevice;
|
DEVICE_e eDevice = pMD->eDevice;
|
||||||
MemoryView_e iView = pMD->eView;
|
MemoryView_e iView = pMD->eView;
|
||||||
|
|
||||||
SS_CARD_MOCKINGBOARD SS_MB;
|
SS_CARD_MOCKINGBOARD_v1 SS_MB;
|
||||||
|
|
||||||
if ((eDevice == DEV_SY6522) || (eDevice == DEV_AY8910))
|
if ((eDevice == DEV_SY6522) || (eDevice == DEV_AY8910))
|
||||||
MB_GetSnapshot(&SS_MB, 4+(nAddr>>1)); // Slot4 or Slot5
|
MB_GetSnapshot_v1(&SS_MB, 4+(nAddr>>1)); // Slot4 or Slot5
|
||||||
|
|
||||||
int nFontWidth = g_aFontConfig[ FONT_INFO ]._nFontWidthAvg;
|
int nFontWidth = g_aFontConfig[ FONT_INFO ]._nFontWidthAvg;
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ Update_t Help_Arg_1( int iCommandHelp )
|
||||||
{
|
{
|
||||||
_Arg_1( iCommandHelp );
|
_Arg_1( iCommandHelp );
|
||||||
|
|
||||||
wsprintf( g_aArgs[ 1 ].sArg, g_aCommands[ iCommandHelp ].m_sName ); // .3 Fixed: Help_Arg_1() now copies command name into arg.name
|
wsprintf( g_aArgs[ 1 ].sArg, "%s", g_aCommands[ iCommandHelp ].m_sName ); // .3 Fixed: Help_Arg_1() now copies command name into arg.name
|
||||||
|
|
||||||
return CmdHelpSpecific( 1 );
|
return CmdHelpSpecific( 1 );
|
||||||
}
|
}
|
||||||
|
@ -669,49 +669,49 @@ Update_t CmdHelpSpecific (int nArgs)
|
||||||
|
|
||||||
// HACK: Major kludge to display category!!!
|
// HACK: Major kludge to display category!!!
|
||||||
if (iCmd <= CMD_UNASSEMBLE)
|
if (iCmd <= CMD_UNASSEMBLE)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_CPU ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_CPU ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_BOOKMARK_SAVE)
|
if (iCmd <= CMD_BOOKMARK_SAVE)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_BOOKMARKS ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_BOOKMARKS ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_BREAKPOINT_SAVE)
|
if (iCmd <= CMD_BREAKPOINT_SAVE)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_BREAKPOINTS ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_BREAKPOINTS ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_CONFIG_SAVE)
|
if (iCmd <= CMD_CONFIG_SAVE)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_CONFIG ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_CONFIG ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_CURSOR_PAGE_DOWN_4K)
|
if (iCmd <= CMD_CURSOR_PAGE_DOWN_4K)
|
||||||
wsprintf( sCategory, "Scrolling" );
|
wsprintf( sCategory, "Scrolling" );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_FLAG_SET_N)
|
if (iCmd <= CMD_FLAG_SET_N)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_FLAGS ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_FLAGS ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_MOTD)
|
if (iCmd <= CMD_MOTD)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_HELP ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_HELP ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_MEMORY_FILL)
|
if (iCmd <= CMD_MEMORY_FILL)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_MEMORY ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_MEMORY ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_OUTPUT_RUN)
|
if (iCmd <= CMD_OUTPUT_RUN)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_OUTPUT ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_OUTPUT ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_SYNC)
|
if (iCmd <= CMD_SYNC)
|
||||||
wsprintf( sCategory, "Source" );
|
wsprintf( sCategory, "Source" );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_SYMBOLS_LIST)
|
if (iCmd <= CMD_SYMBOLS_LIST)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_SYMBOLS ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_SYMBOLS ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_VIEW_DHGR2)
|
if (iCmd <= CMD_VIEW_DHGR2)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_VIEW ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_VIEW ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_WATCH_SAVE)
|
if (iCmd <= CMD_WATCH_SAVE)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_WATCHES ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_WATCHES ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_WINDOW_OUTPUT)
|
if (iCmd <= CMD_WINDOW_OUTPUT)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_WINDOW ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_WINDOW ].m_sName );
|
||||||
else
|
else
|
||||||
if (iCmd <= CMD_ZEROPAGE_POINTER_SAVE)
|
if (iCmd <= CMD_ZEROPAGE_POINTER_SAVE)
|
||||||
wsprintf( sCategory, g_aParameters[ PARAM_CAT_ZEROPAGE ].m_sName );
|
wsprintf( sCategory, "%s", g_aParameters[ PARAM_CAT_ZEROPAGE ].m_sName );
|
||||||
else
|
else
|
||||||
wsprintf( sCategory, "Unknown!" );
|
wsprintf( sCategory, "Unknown!" );
|
||||||
|
|
||||||
|
|
624
source/Disk.cpp
624
source/Disk.cpp
|
@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows
|
||||||
Copyright (C) 1994-1996, Michael O'Brien
|
Copyright (C) 1994-1996, Michael O'Brien
|
||||||
Copyright (C) 1999-2001, Oliver Schmidt
|
Copyright (C) 1999-2001, Oliver Schmidt
|
||||||
Copyright (C) 2002-2005, Tom Charlesworth
|
Copyright (C) 2002-2005, Tom Charlesworth
|
||||||
Copyright (C) 2006-2014, Tom Charlesworth, Michael Pohoreski
|
Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski, Nick Westgate
|
||||||
|
|
||||||
AppleWin is free software; you can redistribute it and/or modify
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,21 +24,31 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
/* Description: Disk
|
/* Description: Disk
|
||||||
*
|
*
|
||||||
* Author: Various
|
* Author: Various
|
||||||
|
*
|
||||||
|
* In comments, UTA2E is an abbreviation for a reference to "Understanding the Apple //e" by James Sather
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "SaveState_Structs_v1.h"
|
||||||
|
|
||||||
#include "AppleWin.h"
|
#include "AppleWin.h"
|
||||||
#include "Disk.h"
|
#include "Disk.h"
|
||||||
#include "DiskImage.h"
|
#include "DiskImage.h"
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
|
#include "Log.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
#include "Video.h"
|
#include "Video.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#include "..\resource\resource.h"
|
#include "..\resource\resource.h"
|
||||||
|
|
||||||
#define LOG_DISK_ENABLED 0
|
#define LOG_DISK_ENABLED 0
|
||||||
|
#define LOG_DISK_TRACKS 1
|
||||||
|
#define LOG_DISK_MOTOR 0
|
||||||
|
#define LOG_DISK_PHASES 0
|
||||||
|
#define LOG_DISK_NIBBLES 0
|
||||||
|
|
||||||
// __VA_ARGS__ not supported on MSVC++ .NET 7.x
|
// __VA_ARGS__ not supported on MSVC++ .NET 7.x
|
||||||
#if (LOG_DISK_ENABLED)
|
#if (LOG_DISK_ENABLED)
|
||||||
|
@ -61,21 +71,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
// Private ________________________________________________________________________________________
|
// Private ________________________________________________________________________________________
|
||||||
|
|
||||||
const int MAX_DISK_IMAGE_NAME = 15;
|
|
||||||
const int MAX_DISK_FULL_NAME = 127;
|
|
||||||
|
|
||||||
struct Disk_t
|
struct Disk_t
|
||||||
{
|
{
|
||||||
TCHAR imagename[ MAX_DISK_IMAGE_NAME + 1 ]; // <FILENAME> (ie. no extension)
|
TCHAR imagename[ MAX_DISK_IMAGE_NAME + 1 ]; // <FILENAME> (ie. no extension)
|
||||||
TCHAR fullname [ MAX_DISK_FULL_NAME + 1 ]; // <FILENAME.EXT> or <FILENAME.zip> : This is persisted to the snapshot file
|
TCHAR fullname [ MAX_DISK_FULL_NAME + 1 ]; // <FILENAME.EXT> or <FILENAME.zip> : This is persisted to the snapshot file
|
||||||
std::string strDiskPathFilename;
|
std::string strFilenameInZip; // "" or <FILENAME.EXT>
|
||||||
std::string strFilenameInZip; // 0x00 or <FILENAME.EXT>
|
|
||||||
HIMAGE imagehandle; // Init'd by DiskInsert() -> ImageOpen()
|
HIMAGE imagehandle; // Init'd by DiskInsert() -> ImageOpen()
|
||||||
|
bool bWriteProtected;
|
||||||
|
//
|
||||||
int track;
|
int track;
|
||||||
LPBYTE trackimage;
|
LPBYTE trackimage;
|
||||||
int phase;
|
int phase;
|
||||||
int byte;
|
int byte;
|
||||||
bool bWriteProtected;
|
|
||||||
BOOL trackimagedata;
|
BOOL trackimagedata;
|
||||||
BOOL trackimagedirty;
|
BOOL trackimagedirty;
|
||||||
DWORD spinning;
|
DWORD spinning;
|
||||||
|
@ -86,14 +93,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
{
|
{
|
||||||
memcpy(imagename, other.imagename, sizeof(imagename));
|
memcpy(imagename, other.imagename, sizeof(imagename));
|
||||||
memcpy(fullname , other.fullname, sizeof(fullname));
|
memcpy(fullname , other.fullname, sizeof(fullname));
|
||||||
strDiskPathFilename = other.strDiskPathFilename;
|
|
||||||
strFilenameInZip = other.strFilenameInZip;
|
strFilenameInZip = other.strFilenameInZip;
|
||||||
imagehandle = other.imagehandle;
|
imagehandle = other.imagehandle;
|
||||||
|
bWriteProtected = other.bWriteProtected;
|
||||||
track = other.track;
|
track = other.track;
|
||||||
trackimage = other.trackimage;
|
trackimage = other.trackimage;
|
||||||
phase = other.phase;
|
phase = other.phase;
|
||||||
byte = other.byte;
|
byte = other.byte;
|
||||||
bWriteProtected = other.bWriteProtected;
|
|
||||||
trackimagedata = other.trackimagedata;
|
trackimagedata = other.trackimagedata;
|
||||||
trackimagedirty = other.trackimagedirty;
|
trackimagedirty = other.trackimagedirty;
|
||||||
spinning = other.spinning;
|
spinning = other.spinning;
|
||||||
|
@ -108,9 +114,11 @@ static BOOL diskaccessed = 0;
|
||||||
static Disk_t g_aFloppyDisk[NUM_DRIVES];
|
static Disk_t g_aFloppyDisk[NUM_DRIVES];
|
||||||
static BYTE floppylatch = 0;
|
static BYTE floppylatch = 0;
|
||||||
static BOOL floppymotoron = 0;
|
static BOOL floppymotoron = 0;
|
||||||
|
static BOOL floppyloadmode = 0; // for efficiency this is not used; it's extremely unlikely to affect emulation (nickw)
|
||||||
static BOOL floppywritemode = 0;
|
static BOOL floppywritemode = 0;
|
||||||
static WORD phases; // state bits for stepper magnet phases 0 - 3
|
static WORD phases = 0; // state bits for stepper magnet phases 0 - 3
|
||||||
static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry
|
static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry
|
||||||
|
static UINT g_uSlot = 0;
|
||||||
|
|
||||||
static void CheckSpinning();
|
static void CheckSpinning();
|
||||||
static Disk_Status_e GetDriveLightStatus( const int iDrive );
|
static Disk_Status_e GetDriveLightStatus( const int iDrive );
|
||||||
|
@ -118,6 +126,7 @@ static bool IsDriveValid( const int iDrive );
|
||||||
static void ReadTrack (int drive);
|
static void ReadTrack (int drive);
|
||||||
static void RemoveDisk (int drive);
|
static void RemoveDisk (int drive);
|
||||||
static void WriteTrack (int drive);
|
static void WriteTrack (int drive);
|
||||||
|
static LPCTSTR DiskGetFullPathName(const int iDrive);
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
@ -127,14 +136,9 @@ int DiskGetCurrentPhase(void) { return g_aFloppyDisk[currdrive].phase; }
|
||||||
int DiskGetCurrentOffset(void) { return g_aFloppyDisk[currdrive].byte; }
|
int DiskGetCurrentOffset(void) { return g_aFloppyDisk[currdrive].byte; }
|
||||||
int DiskGetTrack( int drive ) { return g_aFloppyDisk[ drive ].track; }
|
int DiskGetTrack( int drive ) { return g_aFloppyDisk[ drive ].track; }
|
||||||
|
|
||||||
const std::string& DiskGetDiskPathFilename(const int iDrive)
|
const char* DiskGetDiskPathFilename(const int iDrive)
|
||||||
{
|
{
|
||||||
return g_aFloppyDisk[iDrive].strDiskPathFilename;
|
return g_aFloppyDisk[iDrive].fullname;
|
||||||
}
|
|
||||||
|
|
||||||
static void DiskSetDiskPathFilename(const int iDrive, const std::string strPathName)
|
|
||||||
{
|
|
||||||
g_aFloppyDisk[iDrive].strDiskPathFilename = strPathName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* DiskGetCurrentState(void)
|
char* DiskGetCurrentState(void)
|
||||||
|
@ -152,19 +156,27 @@ char* DiskGetCurrentState(void)
|
||||||
else if (floppywritemode)
|
else if (floppywritemode)
|
||||||
{
|
{
|
||||||
if (g_aFloppyDisk[currdrive].bWriteProtected)
|
if (g_aFloppyDisk[currdrive].bWriteProtected)
|
||||||
return "Writing";
|
|
||||||
else
|
|
||||||
return "Writing (write protected)";
|
return "Writing (write protected)";
|
||||||
|
else
|
||||||
|
return "Writing";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*if (floppyloadmode)
|
||||||
|
{
|
||||||
|
if (g_aFloppyDisk[currdrive].bWriteProtected)
|
||||||
|
return "Reading write protect state (write protected)";
|
||||||
|
else
|
||||||
|
return "Reading write protect state (not write protected)";
|
||||||
|
}
|
||||||
|
else*/
|
||||||
return "Reading";
|
return "Reading";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void Disk_LoadLastDiskImage(const int iDrive)
|
void Disk_LoadLastDiskImage(const int iDrive)
|
||||||
{
|
{
|
||||||
_ASSERT(iDrive == DRIVE_1 || iDrive == DRIVE_2);
|
_ASSERT(iDrive == DRIVE_1 || iDrive == DRIVE_2);
|
||||||
|
|
||||||
|
@ -175,22 +187,15 @@ char* DiskGetCurrentState(void)
|
||||||
? REGVALUE_PREF_LAST_DISK_1
|
? REGVALUE_PREF_LAST_DISK_1
|
||||||
: REGVALUE_PREF_LAST_DISK_2;
|
: REGVALUE_PREF_LAST_DISK_2;
|
||||||
|
|
||||||
if (RegLoadString(TEXT(REG_PREFS),pRegKey,1,sFilePath,MAX_PATH))
|
if (RegLoadString(TEXT(REG_PREFS), pRegKey, 1, sFilePath, MAX_PATH))
|
||||||
{
|
{
|
||||||
sFilePath[ MAX_PATH ] = 0;
|
sFilePath[ MAX_PATH ] = 0;
|
||||||
DiskSetDiskPathFilename(iDrive, sFilePath);
|
|
||||||
|
|
||||||
#if _DEBUG
|
|
||||||
// MessageBox(g_hFrameWindow,pFileName,pRegKey,MB_OK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// _tcscat(imagefilename,TEXT("MASTER.DSK")); // TODO: Should remember last disk by user
|
|
||||||
g_bSaveDiskImage = false;
|
g_bSaveDiskImage = false;
|
||||||
// Pass in ptr to local copy of filepath, since RemoveDisk() sets DiskPathFilename = ""
|
// Pass in ptr to local copy of filepath, since RemoveDisk() sets DiskPathFilename = ""
|
||||||
DiskInsert(iDrive, sFilePath, IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE);
|
DiskInsert(iDrive, sFilePath, IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE);
|
||||||
g_bSaveDiskImage = true;
|
g_bSaveDiskImage = true;
|
||||||
}
|
}
|
||||||
//else MessageBox(g_hFrameWindow,"Reg Key/Value not found",pRegKey,MB_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -202,12 +207,23 @@ void Disk_SaveLastDiskImage(const int iDrive)
|
||||||
if (!g_bSaveDiskImage)
|
if (!g_bSaveDiskImage)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char *pFileName = DiskGetDiskPathFilename(iDrive).c_str();
|
const char *pFileName = g_aFloppyDisk[iDrive].fullname;
|
||||||
|
|
||||||
if (iDrive == DRIVE_1)
|
if (iDrive == DRIVE_1)
|
||||||
RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_DISK_1, TRUE, pFileName);
|
RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_DISK_1, TRUE, pFileName);
|
||||||
else
|
else
|
||||||
RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_DISK_2, TRUE, pFileName);
|
RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_DISK_2, TRUE, pFileName);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
char szPathName[MAX_PATH];
|
||||||
|
strcpy(szPathName, DiskGetFullPathName(iDrive));
|
||||||
|
if (_tcsrchr(szPathName, TEXT('\\')))
|
||||||
|
{
|
||||||
|
char* pPathEnd = _tcsrchr(szPathName, TEXT('\\'))+1;
|
||||||
|
*pPathEnd = 0;
|
||||||
|
RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, szPathName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -249,53 +265,6 @@ static Disk_Status_e GetDriveLightStatus(const int iDrive)
|
||||||
return DISK_STATUS_OFF;
|
return DISK_STATUS_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
static void GetImageTitle(LPCTSTR imagefilename, Disk_t* fptr)
|
|
||||||
{
|
|
||||||
TCHAR imagetitle[ MAX_DISK_FULL_NAME+1 ];
|
|
||||||
LPCTSTR startpos = imagefilename;
|
|
||||||
|
|
||||||
// imagetitle = <FILENAME.EXT>
|
|
||||||
if (_tcsrchr(startpos,TEXT('\\')))
|
|
||||||
startpos = _tcsrchr(startpos,TEXT('\\'))+1;
|
|
||||||
|
|
||||||
_tcsncpy(imagetitle,startpos,MAX_DISK_FULL_NAME);
|
|
||||||
imagetitle[MAX_DISK_FULL_NAME] = 0;
|
|
||||||
|
|
||||||
// if imagetitle contains a lowercase char, then found=1 (why?)
|
|
||||||
BOOL found = 0;
|
|
||||||
int loop = 0;
|
|
||||||
while (imagetitle[loop] && !found)
|
|
||||||
{
|
|
||||||
if (IsCharLower(imagetitle[loop]))
|
|
||||||
found = 1;
|
|
||||||
else
|
|
||||||
loop++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!found) && (loop > 2))
|
|
||||||
CharLowerBuff(imagetitle+1,_tcslen(imagetitle+1));
|
|
||||||
|
|
||||||
// fptr->fullname = <FILENAME.EXT>
|
|
||||||
_tcsncpy( fptr->fullname, imagetitle, MAX_DISK_FULL_NAME );
|
|
||||||
fptr->fullname[ MAX_DISK_FULL_NAME ] = 0;
|
|
||||||
|
|
||||||
if (imagetitle[0])
|
|
||||||
{
|
|
||||||
LPTSTR dot = imagetitle;
|
|
||||||
if (_tcsrchr(dot,TEXT('.')))
|
|
||||||
dot = _tcsrchr(dot,TEXT('.'));
|
|
||||||
if (dot > imagetitle)
|
|
||||||
*dot = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fptr->imagename = <FILENAME> (ie. no extension)
|
|
||||||
_tcsncpy( fptr->imagename, imagetitle, MAX_DISK_IMAGE_NAME );
|
|
||||||
fptr->imagename[ MAX_DISK_IMAGE_NAME ] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static bool IsDriveValid(const int iDrive)
|
static bool IsDriveValid(const int iDrive)
|
||||||
|
@ -331,8 +300,9 @@ static void ReadTrack(const int iDrive)
|
||||||
|
|
||||||
if (pFloppy->trackimage && pFloppy->imagehandle)
|
if (pFloppy->trackimage && pFloppy->imagehandle)
|
||||||
{
|
{
|
||||||
LOG_DISK("read track %2X%s\r", pFloppy->track, (pFloppy->phase & 1) ? ".5" : "");
|
#if LOG_DISK_TRACKS
|
||||||
|
LOG_DISK("track $%02X%s read\r\n", pFloppy->track, (pFloppy->phase & 1) ? ".5" : " ");
|
||||||
|
#endif
|
||||||
ImageReadTrack(
|
ImageReadTrack(
|
||||||
pFloppy->imagehandle,
|
pFloppy->imagehandle,
|
||||||
pFloppy->track,
|
pFloppy->track,
|
||||||
|
@ -370,7 +340,6 @@ static void RemoveDisk(const int iDrive)
|
||||||
memset( pFloppy->imagename, 0, MAX_DISK_IMAGE_NAME+1 );
|
memset( pFloppy->imagename, 0, MAX_DISK_IMAGE_NAME+1 );
|
||||||
memset( pFloppy->fullname , 0, MAX_DISK_FULL_NAME +1 );
|
memset( pFloppy->fullname , 0, MAX_DISK_FULL_NAME +1 );
|
||||||
pFloppy->strFilenameInZip = "";
|
pFloppy->strFilenameInZip = "";
|
||||||
DiskSetDiskPathFilename(iDrive, "");
|
|
||||||
|
|
||||||
Disk_SaveLastDiskImage( iDrive );
|
Disk_SaveLastDiskImage( iDrive );
|
||||||
Video_ResetScreenshotCounter( NULL );
|
Video_ResetScreenshotCounter( NULL );
|
||||||
|
@ -389,12 +358,17 @@ static void WriteTrack(const int iDrive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pFloppy->trackimage && pFloppy->imagehandle)
|
if (pFloppy->trackimage && pFloppy->imagehandle)
|
||||||
|
{
|
||||||
|
#if LOG_DISK_TRACKS
|
||||||
|
LOG_DISK("track $%02X%s write\r\n", pFloppy->track, (pFloppy->phase & 0) ? ".5" : " "); // TODO: hard-coded to whole tracks - see below (nickw)
|
||||||
|
#endif
|
||||||
ImageWriteTrack(
|
ImageWriteTrack(
|
||||||
pFloppy->imagehandle,
|
pFloppy->imagehandle,
|
||||||
pFloppy->track,
|
pFloppy->track,
|
||||||
pFloppy->phase,
|
pFloppy->phase, // TODO: this should never be used; it's the current phase (half-track), not that of the track to be written (nickw)
|
||||||
pFloppy->trackimage,
|
pFloppy->trackimage,
|
||||||
pFloppy->nibbles );
|
pFloppy->nibbles);
|
||||||
|
}
|
||||||
|
|
||||||
pFloppy->trackimagedirty = 0;
|
pFloppy->trackimagedirty = 0;
|
||||||
}
|
}
|
||||||
|
@ -415,34 +389,34 @@ void DiskBoot(void)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskControlMotor(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskControlMotor(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
||||||
{
|
{
|
||||||
floppymotoron = address & 1;
|
floppymotoron = address & 1;
|
||||||
|
#if LOG_DISK_MOTOR
|
||||||
|
LOG_DISK("motor %s\r\n", (floppymotoron) ? "on" : "off");
|
||||||
|
#endif
|
||||||
CheckSpinning();
|
CheckSpinning();
|
||||||
return MemReadFloatingBus(1, uExecutedCycles); // TC-TODO: Check b7 always set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
||||||
{
|
{
|
||||||
Disk_t * fptr = &g_aFloppyDisk[currdrive];
|
Disk_t * fptr = &g_aFloppyDisk[currdrive];
|
||||||
#if 1
|
|
||||||
int phase = (address >> 1) & 3;
|
int phase = (address >> 1) & 3;
|
||||||
int phase_bit = (1 << phase);
|
int phase_bit = (1 << phase);
|
||||||
|
|
||||||
|
#if 1
|
||||||
// update the magnet states
|
// update the magnet states
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
{
|
{
|
||||||
// phase on
|
// phase on
|
||||||
phases |= phase_bit;
|
phases |= phase_bit;
|
||||||
LOG_DISK("track %02X phases %X phase %d on address $C0E%X\r", fptr->phase, phases, phase, address & 0xF);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// phase off
|
// phase off
|
||||||
phases &= ~phase_bit;
|
phases &= ~phase_bit;
|
||||||
LOG_DISK("track %02X phases %X phase %d off address $C0E%X\r", fptr->phase, phases, phase, address & 0xF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for any stepping effect from a magnet
|
// check for any stepping effect from a magnet
|
||||||
|
@ -463,7 +437,6 @@ static BYTE __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG u
|
||||||
const int nNumTracksInImage = ImageGetNumTracks(fptr->imagehandle);
|
const int nNumTracksInImage = ImageGetNumTracks(fptr->imagehandle);
|
||||||
const int newtrack = (nNumTracksInImage == 0) ? 0
|
const int newtrack = (nNumTracksInImage == 0) ? 0
|
||||||
: MIN(nNumTracksInImage-1, fptr->phase >> 1); // (round half tracks down)
|
: MIN(nNumTracksInImage-1, fptr->phase >> 1); // (round half tracks down)
|
||||||
LOG_DISK("newtrack %2X%s\r", newtrack, (fptr->phase & 1) ? ".5" : "");
|
|
||||||
if (newtrack != fptr->track)
|
if (newtrack != fptr->track)
|
||||||
{
|
{
|
||||||
if (fptr->trackimage && fptr->trackimagedirty)
|
if (fptr->trackimage && fptr->trackimagedirty)
|
||||||
|
@ -478,31 +451,21 @@ static BYTE __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG u
|
||||||
// https://github.com/AppleWin/AppleWin/issues/201
|
// https://github.com/AppleWin/AppleWin/issues/201
|
||||||
FrameDrawDiskStatus( (HDC)0 );
|
FrameDrawDiskStatus( (HDC)0 );
|
||||||
}
|
}
|
||||||
#else // Old 1.13.1 code for Chessmaster 2000 to work! (see bug#18109)
|
#else
|
||||||
const int nNumTracksInImage = ImageGetNumTracks(fptr->imagehandle);
|
// substitute alternate stepping code here to test
|
||||||
if (address & 1) {
|
#endif
|
||||||
int phase = (address >> 1) & 3;
|
#if LOG_DISK_PHASES
|
||||||
int direction = 0;
|
LOG_DISK("track $%02X%s phases %d%d%d%d phase %d %s address $%4X\r\n",
|
||||||
if (phase == ((fptr->phase+1) & 3))
|
fptr->phase >> 1,
|
||||||
direction = 1;
|
(fptr->phase & 1) ? ".5" : " ",
|
||||||
if (phase == ((fptr->phase+3) & 3))
|
(phases >> 3) & 1,
|
||||||
direction = -1;
|
(phases >> 2) & 1,
|
||||||
if (direction) {
|
(phases >> 1) & 1,
|
||||||
fptr->phase = MAX(0,MIN(79,fptr->phase+direction));
|
(phases >> 0) & 1,
|
||||||
if (!(fptr->phase & 1)) {
|
phase,
|
||||||
int newtrack = MIN(nNumTracksInImage-1,fptr->phase >> 1);
|
(address & 1) ? "on " : "off",
|
||||||
if (newtrack != fptr->track) {
|
address);
|
||||||
if (fptr->trackimage && fptr->trackimagedirty)
|
|
||||||
WriteTrack(currdrive);
|
|
||||||
fptr->track = newtrack;
|
|
||||||
fptr->trackimagedata = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return ((address & 0xF) == 0) ? 0xFF // TC-TODO: Check why $C0E0 only returns 0xFF
|
|
||||||
: MemReadFloatingBus(1, uExecutedCycles); // TC-TODO: Check b7 always set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -520,13 +483,12 @@ void DiskDestroy(void)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskEnable(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskEnable(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
||||||
{
|
{
|
||||||
currdrive = address & 1;
|
currdrive = address & 1;
|
||||||
g_aFloppyDisk[!currdrive].spinning = 0;
|
g_aFloppyDisk[!currdrive].spinning = 0;
|
||||||
g_aFloppyDisk[!currdrive].writelight = 0;
|
g_aFloppyDisk[!currdrive].writelight = 0;
|
||||||
CheckSpinning();
|
CheckSpinning();
|
||||||
return MemReadFloatingBus(uExecutedCycles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -558,6 +520,11 @@ LPCTSTR DiskGetFullDiskFilename(const int iDrive)
|
||||||
return DiskGetFullName(iDrive);
|
return DiskGetFullName(iDrive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LPCTSTR DiskGetFullPathName(const int iDrive)
|
||||||
|
{
|
||||||
|
return ImageGetPathname(g_aFloppyDisk[iDrive].imagehandle);
|
||||||
|
}
|
||||||
|
|
||||||
// Return the imagename
|
// Return the imagename
|
||||||
// . Used by Drive Button's icons & Property Sheet Page (Save snapshot)
|
// . Used by Drive Button's icons & Property Sheet Page (Save snapshot)
|
||||||
LPCTSTR DiskGetBaseName(const int iDrive)
|
LPCTSTR DiskGetBaseName(const int iDrive)
|
||||||
|
@ -581,7 +548,7 @@ void DiskInitialize(void)
|
||||||
{
|
{
|
||||||
int loop = NUM_DRIVES;
|
int loop = NUM_DRIVES;
|
||||||
while (loop--)
|
while (loop--)
|
||||||
ZeroMemory(&g_aFloppyDisk[loop],sizeof(Disk_t ));
|
ZeroMemory(&g_aFloppyDisk[loop], sizeof(Disk_t));
|
||||||
|
|
||||||
TCHAR imagefilename[MAX_PATH];
|
TCHAR imagefilename[MAX_PATH];
|
||||||
_tcscpy(imagefilename,g_sProgramDir);
|
_tcscpy(imagefilename,g_sProgramDir);
|
||||||
|
@ -611,10 +578,20 @@ ImageError_e DiskInsert(const int iDrive, LPCTSTR pszImageFilename, const bool b
|
||||||
else
|
else
|
||||||
fptr->bWriteProtected = bForceWriteProtected ? true : (dwAttributes & FILE_ATTRIBUTE_READONLY);
|
fptr->bWriteProtected = bForceWriteProtected ? true : (dwAttributes & FILE_ATTRIBUTE_READONLY);
|
||||||
|
|
||||||
// Check if image is being used by the other HDD, and unplug it in order to be swapped
|
// Check if image is being used by the other drive, and if so remove it in order so it can be swapped
|
||||||
std::string otherDisk = DiskGetDiskPathFilename(!iDrive);
|
{
|
||||||
if (!strcmp(otherDisk.c_str(), pszImageFilename)) {
|
const char* pszOtherPathname = DiskGetFullPathName(!iDrive);
|
||||||
|
|
||||||
|
char szCurrentPathname[MAX_PATH];
|
||||||
|
DWORD uNameLen = GetFullPathName(pszImageFilename, MAX_PATH, szCurrentPathname, NULL);
|
||||||
|
if (uNameLen == 0 || uNameLen >= MAX_PATH)
|
||||||
|
strcpy_s(szCurrentPathname, MAX_PATH, pszImageFilename);
|
||||||
|
|
||||||
|
if (!strcmp(pszOtherPathname, szCurrentPathname))
|
||||||
|
{
|
||||||
DiskEject(!iDrive);
|
DiskEject(!iDrive);
|
||||||
|
FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageError_e Error = ImageOpen(pszImageFilename,
|
ImageError_e Error = ImageOpen(pszImageFilename,
|
||||||
|
@ -637,19 +614,15 @@ ImageError_e DiskInsert(const int iDrive, LPCTSTR pszImageFilename, const bool b
|
||||||
|
|
||||||
if (Error == eIMAGE_ERROR_NONE)
|
if (Error == eIMAGE_ERROR_NONE)
|
||||||
{
|
{
|
||||||
GetImageTitle(pszImageFilename, fptr);
|
GetImageTitle(pszImageFilename, fptr->imagename, fptr->fullname);
|
||||||
|
Video_ResetScreenshotCounter(fptr->imagename);
|
||||||
DiskSetDiskPathFilename(iDrive, pszImageFilename);
|
|
||||||
|
|
||||||
//MessageBox( g_hFrameWindow, imagefilename, fptr->imagename, MB_OK );
|
|
||||||
Video_ResetScreenshotCounter( fptr->imagename );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Video_ResetScreenshotCounter( NULL );
|
Video_ResetScreenshotCounter(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Disk_SaveLastDiskImage( iDrive );
|
Disk_SaveLastDiskImage(iDrive);
|
||||||
|
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
|
@ -730,6 +703,13 @@ void DiskNotifyInvalidImage(const int iDrive, LPCTSTR pszImageFilename, const Im
|
||||||
pszImageFilename);
|
pszImageFilename);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case eIMAGE_ERROR_FAILED_TO_GET_PATHNAME:
|
||||||
|
wsprintf(
|
||||||
|
szBuffer,
|
||||||
|
TEXT("Unable to GetFullPathName() for the file: %s."),
|
||||||
|
pszImageFilename);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// IGNORE OTHER ERRORS SILENTLY
|
// IGNORE OTHER ERRORS SILENTLY
|
||||||
return;
|
return;
|
||||||
|
@ -793,8 +773,9 @@ bool Disk_IsDriveEmpty(const int iDrive)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskReadWrite (WORD programcounter, WORD, BYTE, BYTE, ULONG)
|
static void __stdcall DiskReadWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
||||||
{
|
{
|
||||||
|
/* floppyloadmode = 0; */
|
||||||
Disk_t * fptr = &g_aFloppyDisk[currdrive];
|
Disk_t * fptr = &g_aFloppyDisk[currdrive];
|
||||||
|
|
||||||
diskaccessed = 1;
|
diskaccessed = 1;
|
||||||
|
@ -803,32 +784,23 @@ static BYTE __stdcall DiskReadWrite (WORD programcounter, WORD, BYTE, BYTE, ULON
|
||||||
ReadTrack(currdrive);
|
ReadTrack(currdrive);
|
||||||
|
|
||||||
if (!fptr->trackimagedata)
|
if (!fptr->trackimagedata)
|
||||||
return 0xFF;
|
{
|
||||||
|
floppylatch = 0xFF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BYTE result = 0;
|
if (!floppywritemode)
|
||||||
|
|
||||||
if (!floppywritemode || !fptr->bWriteProtected)
|
|
||||||
{
|
{
|
||||||
if (floppywritemode)
|
floppylatch = *(fptr->trackimage + fptr->byte);
|
||||||
|
#if LOG_DISK_NIBBLES
|
||||||
|
LOG_DISK("read %4X = %2X\r\n", fptr->byte, floppylatch);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if ((floppylatch & 0x80) && !fptr->bWriteProtected) // && floppywritemode
|
||||||
{
|
{
|
||||||
if (floppylatch & 0x80)
|
*(fptr->trackimage + fptr->byte) = floppylatch;
|
||||||
{
|
|
||||||
*(fptr->trackimage+fptr->byte) = floppylatch;
|
|
||||||
fptr->trackimagedirty = 1;
|
fptr->trackimagedirty = 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = *(fptr->trackimage+fptr->byte);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
{ LOG_DISK("nib %4X = %2X\r", fptr->byte, result); }
|
|
||||||
|
|
||||||
if (++fptr->byte >= fptr->nibbles)
|
if (++fptr->byte >= fptr->nibbles)
|
||||||
fptr->byte = 0;
|
fptr->byte = 0;
|
||||||
|
@ -838,8 +810,6 @@ static BYTE __stdcall DiskReadWrite (WORD programcounter, WORD, BYTE, BYTE, ULON
|
||||||
// NB. Prevent flooding of forcing UI to redraw!!!
|
// NB. Prevent flooding of forcing UI to redraw!!!
|
||||||
if( ((fptr->byte) & 0xFF) == 0 )
|
if( ((fptr->byte) & 0xFF) == 0 )
|
||||||
FrameDrawDiskStatus( (HDC)0 );
|
FrameDrawDiskStatus( (HDC)0 );
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -852,7 +822,7 @@ void DiskReset(void)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void DiskSelectImage(const int iDrive, LPSTR pszFilename)
|
static bool DiskSelectImage(const int iDrive, LPCSTR pszFilename)
|
||||||
{
|
{
|
||||||
TCHAR directory[MAX_PATH] = TEXT("");
|
TCHAR directory[MAX_PATH] = TEXT("");
|
||||||
TCHAR filename[MAX_PATH] = TEXT("");
|
TCHAR filename[MAX_PATH] = TEXT("");
|
||||||
|
@ -880,6 +850,8 @@ void DiskSelectImage(const int iDrive, LPSTR pszFilename)
|
||||||
ofn.Flags = OFN_PATHMUSTEXIST;
|
ofn.Flags = OFN_PATHMUSTEXIST;
|
||||||
ofn.lpstrTitle = title;
|
ofn.lpstrTitle = title;
|
||||||
|
|
||||||
|
bool bRes = false;
|
||||||
|
|
||||||
if (GetOpenFileName(&ofn))
|
if (GetOpenFileName(&ofn))
|
||||||
{
|
{
|
||||||
if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension])
|
if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension])
|
||||||
|
@ -888,16 +860,15 @@ void DiskSelectImage(const int iDrive, LPSTR pszFilename)
|
||||||
ImageError_e Error = DiskInsert(iDrive, filename, ofn.Flags & OFN_READONLY, IMAGE_CREATE);
|
ImageError_e Error = DiskInsert(iDrive, filename, ofn.Flags & OFN_READONLY, IMAGE_CREATE);
|
||||||
if (Error == eIMAGE_ERROR_NONE)
|
if (Error == eIMAGE_ERROR_NONE)
|
||||||
{
|
{
|
||||||
DiskSetDiskPathFilename(iDrive, filename);
|
bRes = true;
|
||||||
filename[ofn.nFileOffset] = 0;
|
|
||||||
if (_tcsicmp(directory, filename))
|
|
||||||
RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, filename);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DiskNotifyInvalidImage(iDrive, filename, Error);
|
DiskNotifyInvalidImage(iDrive, filename, Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return bRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -909,24 +880,31 @@ void DiskSelect(const int iDrive)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskSetLatchValue(WORD, WORD, BYTE write, BYTE value, ULONG)
|
static void __stdcall DiskLoadWriteProtect(WORD, WORD, BYTE write, BYTE value, ULONG) {
|
||||||
{
|
/* floppyloadmode = 1; */
|
||||||
if (write)
|
if (!write)
|
||||||
floppylatch = value;
|
{
|
||||||
return floppylatch;
|
if (floppymotoron && !floppywritemode)
|
||||||
|
{
|
||||||
|
// phase 1 on also forces write protect in the Disk II drive (UTA2E page 9-7) but we don't implement that
|
||||||
|
if (g_aFloppyDisk[currdrive].bWriteProtected)
|
||||||
|
floppylatch |= 0x80;
|
||||||
|
else
|
||||||
|
floppylatch &= 0x7F;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskSetReadMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskSetReadMode(WORD, WORD, BYTE, BYTE, ULONG)
|
||||||
{
|
{
|
||||||
floppywritemode = 0;
|
floppywritemode = 0;
|
||||||
return MemReadFloatingBus(g_aFloppyDisk[currdrive].bWriteProtected, uExecutedCycles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskSetWriteMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskSetWriteMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles)
|
||||||
{
|
{
|
||||||
floppywritemode = 1;
|
floppywritemode = 1;
|
||||||
BOOL modechange = !g_aFloppyDisk[currdrive].writelight;
|
BOOL modechange = !g_aFloppyDisk[currdrive].writelight;
|
||||||
|
@ -936,8 +914,6 @@ static BYTE __stdcall DiskSetWriteMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCy
|
||||||
//FrameRefreshStatus(DRAW_LEDS);
|
//FrameRefreshStatus(DRAW_LEDS);
|
||||||
FrameDrawDiskLEDS( (HDC)0 );
|
FrameDrawDiskLEDS( (HDC)0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return MemReadFloatingBus(1, uExecutedCycles); // TC-TODO: Check b7 always set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -1032,121 +1008,88 @@ void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot)
|
||||||
|
|
||||||
memcpy(pCxRomPeripheral + uSlot*APPLE_SLOT_SIZE, pData, DISK2_FW_SIZE);
|
memcpy(pCxRomPeripheral + uSlot*APPLE_SLOT_SIZE, pData, DISK2_FW_SIZE);
|
||||||
|
|
||||||
// NB. We used to disable the track stepping delay in the Disk II controller firmware by
|
// Note: We used to disable the track stepping delay in the Disk II controller firmware by
|
||||||
// patching $C64C with $A9,$00,$EA. Now not doing this since:
|
// patching $C64C with $A9,$00,$EA. Now not doing this since:
|
||||||
// . Authentic Speed should be authentic
|
// . Authentic Speed should be authentic
|
||||||
// . Enhanced Speed runs emulation unthrottled, so removing the delay has negligible effect
|
// . Enhanced Speed runs emulation unthrottled, so removing the delay has negligible effect
|
||||||
// . Patching the firmware breaks the ADC checksum used by "The CIA Files" (Tricky Dick)
|
// . Patching the firmware breaks the ADC checksum used by "The CIA Files" (Tricky Dick)
|
||||||
// . In this case we can patch to compensate for an ADC or EOR checksum but not both
|
// . In this case we can patch to compensate for an ADC or EOR checksum but not both (nickw)
|
||||||
|
|
||||||
RegisterIoHandler(uSlot, Disk_IORead, Disk_IOWrite, NULL, NULL, NULL, NULL);
|
RegisterIoHandler(uSlot, Disk_IORead, Disk_IOWrite, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
g_uSlot = uSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall Disk_IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
static BYTE __stdcall Disk_IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
||||||
{
|
{
|
||||||
addr &= 0xFF;
|
switch (addr & 0xF)
|
||||||
|
|
||||||
switch (addr & 0xf)
|
|
||||||
{
|
{
|
||||||
case 0x0: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x0: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x1: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x1: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x2: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x2: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x3: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x3: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x4: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x4: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x5: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x5: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x6: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x6: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x7: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x7: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x8: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x8: DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x9: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x9: DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xA: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xA: DiskEnable(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xB: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xB: DiskEnable(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xC: return DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xC: DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xD: return DiskSetLatchValue(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xD: DiskLoadWriteProtect(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xE: return DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xE: DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xF: return DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xF: DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
// only even addresses return the latch (UTA2E Table 9.1)
|
||||||
|
if (!(addr & 1))
|
||||||
|
return floppylatch;
|
||||||
|
else
|
||||||
|
return MemReadFloatingBus(nCyclesLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BYTE __stdcall Disk_IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
static BYTE __stdcall Disk_IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
||||||
{
|
{
|
||||||
addr &= 0xFF;
|
switch (addr & 0xF)
|
||||||
|
|
||||||
switch (addr & 0xf)
|
|
||||||
{
|
{
|
||||||
case 0x0: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x0: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x1: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x1: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x2: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x2: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x3: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x3: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x4: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x4: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x5: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x5: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x6: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x6: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x7: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x7: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x8: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x8: DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x9: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x9: DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xA: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xA: DiskEnable(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xB: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xB: DiskEnable(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xC: return DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xC: DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xD: return DiskSetLatchValue(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xD: DiskLoadWriteProtect(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xE: return DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xE: DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xF: return DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xF: DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// any address writes the latch via sequencer LD command (74LS323 datasheet)
|
||||||
|
if (floppywritemode /* && floppyloadmode */)
|
||||||
|
{
|
||||||
|
floppylatch = d;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD DiskGetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot)
|
int DiskSetSnapshot_v1(const SS_CARD_DISK2* const pSS)
|
||||||
{
|
{
|
||||||
pSS->Hdr.UnitHdr.dwLength = sizeof(SS_CARD_DISK2);
|
if(pSS->Hdr.UnitHdr.hdr.v1.dwVersion > MAKE_VERSION(1,0,0,2))
|
||||||
pSS->Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,2);
|
|
||||||
|
|
||||||
pSS->Hdr.dwSlot = dwSlot;
|
|
||||||
pSS->Hdr.dwType = CT_Disk2;
|
|
||||||
|
|
||||||
pSS->phases = phases; // new in 1.0.0.2 disk snapshots
|
|
||||||
pSS->currdrive = currdrive; // this was an int in 1.0.0.1 disk snapshots
|
|
||||||
pSS->diskaccessed = diskaccessed;
|
|
||||||
pSS->enhancedisk = enhancedisk;
|
|
||||||
pSS->floppylatch = floppylatch;
|
|
||||||
pSS->floppymotoron = floppymotoron;
|
|
||||||
pSS->floppywritemode = floppywritemode;
|
|
||||||
|
|
||||||
for(UINT i=0; i<NUM_DRIVES; i++)
|
|
||||||
{
|
|
||||||
strcpy(pSS->Unit[i].szFileName, g_aFloppyDisk[i].fullname);
|
|
||||||
pSS->Unit[i].track = g_aFloppyDisk[i].track;
|
|
||||||
pSS->Unit[i].phase = g_aFloppyDisk[i].phase;
|
|
||||||
pSS->Unit[i].byte = g_aFloppyDisk[i].byte;
|
|
||||||
pSS->Unit[i].writeprotected = g_aFloppyDisk[i].bWriteProtected ? TRUE : FALSE;
|
|
||||||
pSS->Unit[i].trackimagedata = g_aFloppyDisk[i].trackimagedata;
|
|
||||||
pSS->Unit[i].trackimagedirty = g_aFloppyDisk[i].trackimagedirty;
|
|
||||||
pSS->Unit[i].spinning = g_aFloppyDisk[i].spinning;
|
|
||||||
pSS->Unit[i].writelight = g_aFloppyDisk[i].writelight;
|
|
||||||
pSS->Unit[i].nibbles = g_aFloppyDisk[i].nibbles;
|
|
||||||
|
|
||||||
if(g_aFloppyDisk[i].trackimage)
|
|
||||||
memcpy(pSS->Unit[i].nTrack, g_aFloppyDisk[i].trackimage, NIBBLES_PER_TRACK);
|
|
||||||
else
|
|
||||||
memset(pSS->Unit[i].nTrack, 0, NIBBLES_PER_TRACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/)
|
|
||||||
{
|
|
||||||
if(pSS->Hdr.UnitHdr.dwVersion > MAKE_VERSION(1,0,0,2))
|
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
phases = pSS->phases; // new in 1.0.0.2 disk snapshots
|
phases = pSS->phases;
|
||||||
currdrive = pSS->currdrive; // this was an int in 1.0.0.1 disk snapshots
|
currdrive = pSS->currdrive;
|
||||||
diskaccessed = pSS->diskaccessed;
|
diskaccessed = pSS->diskaccessed;
|
||||||
enhancedisk = pSS->enhancedisk;
|
enhancedisk = pSS->enhancedisk;
|
||||||
floppylatch = pSS->floppylatch;
|
floppylatch = pSS->floppylatch;
|
||||||
|
@ -1157,7 +1100,7 @@ DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/)
|
||||||
for(UINT i=0; i<NUM_DRIVES; i++)
|
for(UINT i=0; i<NUM_DRIVES; i++)
|
||||||
{
|
{
|
||||||
DiskEject(i); // Remove any disk & update Registry to reflect empty drive
|
DiskEject(i); // Remove any disk & update Registry to reflect empty drive
|
||||||
ZeroMemory(&g_aFloppyDisk[i], sizeof(Disk_t ));
|
ZeroMemory(&g_aFloppyDisk[i], sizeof(Disk_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(UINT i=0; i<NUM_DRIVES; i++)
|
for(UINT i=0; i<NUM_DRIVES; i++)
|
||||||
|
@ -1183,7 +1126,6 @@ DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/)
|
||||||
// DiskInsert() sets up:
|
// DiskInsert() sets up:
|
||||||
// . imagename
|
// . imagename
|
||||||
// . fullname
|
// . fullname
|
||||||
// . strDiskPathFilename
|
|
||||||
// . writeprotected
|
// . writeprotected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1225,3 +1167,181 @@ DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_CARD_DISK2 "Disk]["
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_PHASES "Phases"
|
||||||
|
#define SS_YAML_KEY_CURRENT_DRIVE "Current Drive"
|
||||||
|
#define SS_YAML_KEY_DISK_ACCESSED "Disk Accessed"
|
||||||
|
#define SS_YAML_KEY_ENHANCE_DISK "Enhance Disk"
|
||||||
|
#define SS_YAML_KEY_FLOPPY_LATCH "Floppy Latch"
|
||||||
|
#define SS_YAML_KEY_FLOPPY_MOTOR_ON "Floppy Motor On"
|
||||||
|
#define SS_YAML_KEY_FLOPPY_WRITE_MODE "Floppy Write Mode"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_DISK2UNIT "Unit"
|
||||||
|
#define SS_YAML_KEY_FILENAME "Filename"
|
||||||
|
#define SS_YAML_KEY_TRACK "Track"
|
||||||
|
#define SS_YAML_KEY_PHASE "Phase"
|
||||||
|
#define SS_YAML_KEY_BYTE "Byte"
|
||||||
|
#define SS_YAML_KEY_WRITE_PROTECTED "Write Protected"
|
||||||
|
#define SS_YAML_KEY_SPINNING "Spinning"
|
||||||
|
#define SS_YAML_KEY_WRITE_LIGHT "Write Light"
|
||||||
|
#define SS_YAML_KEY_NIBBLES "Nibbles"
|
||||||
|
#define SS_YAML_KEY_TRACK_IMAGE_DATA "Track Image Data"
|
||||||
|
#define SS_YAML_KEY_TRACK_IMAGE_DIRTY "Track Image Dirty"
|
||||||
|
#define SS_YAML_KEY_TRACK_IMAGE "Track Image"
|
||||||
|
|
||||||
|
std::string DiskGetSnapshotCardName(void)
|
||||||
|
{
|
||||||
|
static const std::string name(SS_YAML_VALUE_CARD_DISK2);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DiskSaveSnapshotDisk2Unit(YamlSaveHelper& yamlSaveHelper, UINT unit)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label label(yamlSaveHelper, "%s%d:\n", SS_YAML_KEY_DISK2UNIT, unit);
|
||||||
|
yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_aFloppyDisk[unit].fullname);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK, g_aFloppyDisk[unit].track);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASE, g_aFloppyDisk[unit].phase);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_BYTE, g_aFloppyDisk[unit].byte);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_WRITE_PROTECTED, g_aFloppyDisk[unit].bWriteProtected);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_SPINNING, g_aFloppyDisk[unit].spinning);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_WRITE_LIGHT, g_aFloppyDisk[unit].writelight);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_NIBBLES, g_aFloppyDisk[unit].nibbles);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK_IMAGE_DATA, g_aFloppyDisk[unit].trackimagedata);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK_IMAGE_DIRTY, g_aFloppyDisk[unit].trackimagedirty);
|
||||||
|
|
||||||
|
if (g_aFloppyDisk[unit].trackimage)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label image(yamlSaveHelper, "%s:\n", SS_YAML_KEY_TRACK_IMAGE);
|
||||||
|
yamlSaveHelper.SaveMemory(g_aFloppyDisk[unit].trackimage, NIBBLES_PER_TRACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Slot slot(yamlSaveHelper, DiskGetSnapshotCardName(), g_uSlot, 1);
|
||||||
|
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_PHASES, phases);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_CURRENT_DRIVE, currdrive);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_DISK_ACCESSED, diskaccessed == TRUE);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_ENHANCE_DISK, enhancedisk == TRUE);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_FLOPPY_LATCH, floppylatch);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_FLOPPY_MOTOR_ON, floppymotoron == TRUE);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_FLOPPY_WRITE_MODE, floppywritemode == TRUE);
|
||||||
|
|
||||||
|
DiskSaveSnapshotDisk2Unit(yamlSaveHelper, DRIVE_1);
|
||||||
|
DiskSaveSnapshotDisk2Unit(yamlSaveHelper, DRIVE_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit)
|
||||||
|
{
|
||||||
|
std::string disk2UnitName = std::string(SS_YAML_KEY_DISK2UNIT) + (unit == DRIVE_1 ? std::string("0") : std::string("1"));
|
||||||
|
if (!yamlLoadHelper.GetSubMap(disk2UnitName))
|
||||||
|
throw std::string("Card: Expected key: ") + disk2UnitName;
|
||||||
|
|
||||||
|
bool bImageError = false;
|
||||||
|
|
||||||
|
g_aFloppyDisk[unit].fullname[0] = 0;
|
||||||
|
g_aFloppyDisk[unit].imagename[0] = 0;
|
||||||
|
g_aFloppyDisk[unit].bWriteProtected = false; // Default to false (until image is successfully loaded below)
|
||||||
|
|
||||||
|
std::string filename = yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME);
|
||||||
|
if (!filename.empty())
|
||||||
|
{
|
||||||
|
DWORD dwAttributes = GetFileAttributes(filename.c_str());
|
||||||
|
if(dwAttributes == INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
// Get user to browse for file
|
||||||
|
DiskSelectImage(unit, filename.c_str());
|
||||||
|
|
||||||
|
dwAttributes = GetFileAttributes(filename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES);
|
||||||
|
if (!bImageError)
|
||||||
|
{
|
||||||
|
if(DiskInsert(unit, filename.c_str(), dwAttributes & FILE_ATTRIBUTE_READONLY, IMAGE_DONT_CREATE) != eIMAGE_ERROR_NONE)
|
||||||
|
bImageError = true;
|
||||||
|
|
||||||
|
// DiskInsert() zeros g_aFloppyDisk[unit], then sets up:
|
||||||
|
// . imagename
|
||||||
|
// . fullname
|
||||||
|
// . writeprotected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_aFloppyDisk[unit].track = yamlLoadHelper.LoadUint(SS_YAML_KEY_TRACK);
|
||||||
|
g_aFloppyDisk[unit].phase = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASE);
|
||||||
|
g_aFloppyDisk[unit].byte = yamlLoadHelper.LoadUint(SS_YAML_KEY_BYTE);
|
||||||
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_WRITE_PROTECTED); // Consume
|
||||||
|
g_aFloppyDisk[unit].spinning = yamlLoadHelper.LoadUint(SS_YAML_KEY_SPINNING);
|
||||||
|
g_aFloppyDisk[unit].writelight = yamlLoadHelper.LoadUint(SS_YAML_KEY_WRITE_LIGHT);
|
||||||
|
g_aFloppyDisk[unit].nibbles = yamlLoadHelper.LoadUint(SS_YAML_KEY_NIBBLES);
|
||||||
|
g_aFloppyDisk[unit].trackimagedata = yamlLoadHelper.LoadUint(SS_YAML_KEY_TRACK_IMAGE_DATA);
|
||||||
|
g_aFloppyDisk[unit].trackimagedirty = yamlLoadHelper.LoadUint(SS_YAML_KEY_TRACK_IMAGE_DIRTY);
|
||||||
|
|
||||||
|
std::auto_ptr<BYTE> pTrack( new BYTE [NIBBLES_PER_TRACK] );
|
||||||
|
memset(pTrack.get(), 0, NIBBLES_PER_TRACK);
|
||||||
|
if (yamlLoadHelper.GetSubMap(SS_YAML_KEY_TRACK_IMAGE))
|
||||||
|
{
|
||||||
|
yamlLoadHelper.LoadMemory(pTrack.get(), NIBBLES_PER_TRACK);
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
if (!filename.empty() && !bImageError)
|
||||||
|
{
|
||||||
|
if ((g_aFloppyDisk[unit].trackimage == NULL) && g_aFloppyDisk[unit].nibbles)
|
||||||
|
AllocTrack(unit);
|
||||||
|
|
||||||
|
if (g_aFloppyDisk[unit].trackimage == NULL)
|
||||||
|
bImageError = true;
|
||||||
|
else
|
||||||
|
memcpy(g_aFloppyDisk[unit].trackimage, pTrack.get(), NIBBLES_PER_TRACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bImageError)
|
||||||
|
{
|
||||||
|
g_aFloppyDisk[unit].trackimagedata = 0;
|
||||||
|
g_aFloppyDisk[unit].trackimagedirty = 0;
|
||||||
|
g_aFloppyDisk[unit].nibbles = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||||
|
{
|
||||||
|
if (slot != 6) // fixme
|
||||||
|
throw std::string("Card: wrong slot");
|
||||||
|
|
||||||
|
if (version != 1)
|
||||||
|
throw std::string("Card: wrong version");
|
||||||
|
|
||||||
|
phases = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASES);
|
||||||
|
currdrive = yamlLoadHelper.LoadUint(SS_YAML_KEY_CURRENT_DRIVE);
|
||||||
|
diskaccessed = yamlLoadHelper.LoadBool(SS_YAML_KEY_DISK_ACCESSED);
|
||||||
|
enhancedisk = yamlLoadHelper.LoadBool(SS_YAML_KEY_ENHANCE_DISK);
|
||||||
|
floppylatch = yamlLoadHelper.LoadUint(SS_YAML_KEY_FLOPPY_LATCH);
|
||||||
|
floppymotoron = yamlLoadHelper.LoadBool(SS_YAML_KEY_FLOPPY_MOTOR_ON);
|
||||||
|
floppywritemode = yamlLoadHelper.LoadBool(SS_YAML_KEY_FLOPPY_WRITE_MODE);
|
||||||
|
|
||||||
|
// Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1
|
||||||
|
for(UINT i=0; i<NUM_DRIVES; i++)
|
||||||
|
{
|
||||||
|
DiskEject(i); // Remove any disk & update Registry to reflect empty drive
|
||||||
|
ZeroMemory(&g_aFloppyDisk[i], sizeof(Disk_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
DiskLoadSnapshotDriveUnit(yamlLoadHelper, DRIVE_1);
|
||||||
|
DiskLoadSnapshotDriveUnit(yamlLoadHelper, DRIVE_2);
|
||||||
|
|
||||||
|
FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ const bool IMAGE_DONT_CREATE = false;
|
||||||
const bool IMAGE_CREATE = true;
|
const bool IMAGE_CREATE = true;
|
||||||
|
|
||||||
extern BOOL enhancedisk;
|
extern BOOL enhancedisk;
|
||||||
const std::string& DiskGetDiskPathFilename(const int iDrive);
|
const char* DiskGetDiskPathFilename(const int iDrive);
|
||||||
|
|
||||||
void DiskInitialize(void); // DiskIIManagerStartup()
|
void DiskInitialize(void); // DiskIIManagerStartup()
|
||||||
void DiskDestroy(void); // no, doesn't "destroy" the disk image. DiskIIManagerShutdown()
|
void DiskDestroy(void); // no, doesn't "destroy" the disk image. DiskIIManagerShutdown()
|
||||||
|
@ -70,8 +70,11 @@ void DiskSelect(const int iDrive);
|
||||||
void DiskUpdatePosition(DWORD);
|
void DiskUpdatePosition(DWORD);
|
||||||
bool DiskDriveSwap(void);
|
bool DiskDriveSwap(void);
|
||||||
void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot);
|
void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot);
|
||||||
DWORD DiskGetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot);
|
|
||||||
DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot);
|
int DiskSetSnapshot_v1(const struct SS_CARD_DISK2* const pSS);
|
||||||
|
std::string DiskGetSnapshotCardName(void);
|
||||||
|
void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||||
|
|
||||||
void Disk_LoadLastDiskImage(const int iDrive);
|
void Disk_LoadLastDiskImage(const int iDrive);
|
||||||
void Disk_SaveLastDiskImage(const int iDrive);
|
void Disk_SaveLastDiskImage(const int iDrive);
|
||||||
|
|
|
@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "Structs.h"
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include "DiskImage.h"
|
#include "DiskImage.h"
|
||||||
|
@ -40,32 +39,37 @@ static CDiskImageHelper sg_DiskImageHelper;
|
||||||
|
|
||||||
// Pre: *pWriteProtected_ already set to file's r/w status - see DiskInsert()
|
// Pre: *pWriteProtected_ already set to file's r/w status - see DiskInsert()
|
||||||
ImageError_e ImageOpen( LPCTSTR pszImageFilename,
|
ImageError_e ImageOpen( LPCTSTR pszImageFilename,
|
||||||
HIMAGE* hDiskImage_,
|
HIMAGE* hDiskImage,
|
||||||
bool* pWriteProtected_,
|
bool* pWriteProtected,
|
||||||
const bool bCreateIfNecessary,
|
const bool bCreateIfNecessary,
|
||||||
std::string& strFilenameInZip)
|
std::string& strFilenameInZip,
|
||||||
|
const bool bExpectFloppy /*=true*/)
|
||||||
{
|
{
|
||||||
if (! (pszImageFilename && hDiskImage_ && pWriteProtected_ && sg_DiskImageHelper.GetWorkBuffer()))
|
if (! (pszImageFilename && hDiskImage && pWriteProtected && sg_DiskImageHelper.GetWorkBuffer()))
|
||||||
return eIMAGE_ERROR_BAD_POINTER;
|
return eIMAGE_ERROR_BAD_POINTER;
|
||||||
|
|
||||||
// CREATE A RECORD FOR THE FILE, AND RETURN AN IMAGE HANDLE
|
// CREATE A RECORD FOR THE FILE, AND RETURN AN IMAGE HANDLE
|
||||||
*hDiskImage_ = (HIMAGE) VirtualAlloc(NULL, sizeof(ImageInfo), MEM_COMMIT, PAGE_READWRITE);
|
*hDiskImage = (HIMAGE) VirtualAlloc(NULL, sizeof(ImageInfo), MEM_COMMIT, PAGE_READWRITE);
|
||||||
if (*hDiskImage_ == NULL)
|
if (*hDiskImage == NULL)
|
||||||
return eIMAGE_ERROR_BAD_POINTER;
|
return eIMAGE_ERROR_BAD_POINTER;
|
||||||
|
|
||||||
ZeroMemory(*hDiskImage_, sizeof(ImageInfo));
|
ZeroMemory(*hDiskImage, sizeof(ImageInfo));
|
||||||
ImageInfo* pImageInfo = (ImageInfo*) *hDiskImage_;
|
ImageInfo* pImageInfo = (ImageInfo*) *hDiskImage;
|
||||||
pImageInfo->bWriteProtected = *pWriteProtected_;
|
pImageInfo->bWriteProtected = *pWriteProtected;
|
||||||
|
|
||||||
ImageError_e Err = sg_DiskImageHelper.Open(pszImageFilename, pImageInfo, bCreateIfNecessary, strFilenameInZip);
|
ImageError_e Err = sg_DiskImageHelper.Open(pszImageFilename, pImageInfo, bCreateIfNecessary, strFilenameInZip);
|
||||||
|
|
||||||
if (pImageInfo->pImageType != NULL && Err == eIMAGE_ERROR_NONE && pImageInfo->pImageType->GetType() == eImageHDV)
|
|
||||||
Err = eIMAGE_ERROR_UNSUPPORTED_HDV;
|
|
||||||
|
|
||||||
if (Err != eIMAGE_ERROR_NONE)
|
if (Err != eIMAGE_ERROR_NONE)
|
||||||
{
|
{
|
||||||
ImageClose(*hDiskImage_, true);
|
ImageClose(*hDiskImage, true);
|
||||||
*hDiskImage_ = (HIMAGE)0;
|
*hDiskImage = (HIMAGE)0;
|
||||||
|
return Err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pImageInfo->pImageType && pImageInfo->pImageType->GetType() == eImageHDV)
|
||||||
|
{
|
||||||
|
if (bExpectFloppy)
|
||||||
|
Err = eIMAGE_ERROR_UNSUPPORTED_HDV;
|
||||||
return Err;
|
return Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +80,7 @@ ImageError_e ImageOpen( LPCTSTR pszImageFilename,
|
||||||
for (UINT uTrack = 0; uTrack < pImageInfo->uNumTracks; uTrack++)
|
for (UINT uTrack = 0; uTrack < pImageInfo->uNumTracks; uTrack++)
|
||||||
pImageInfo->ValidTrack[uTrack] = (pImageInfo->uImageSize > 0) ? 1 : 0;
|
pImageInfo->ValidTrack[uTrack] = (pImageInfo->uImageSize > 0) ? 1 : 0;
|
||||||
|
|
||||||
*pWriteProtected_ = pImageInfo->bWriteProtected;
|
*pWriteProtected = pImageInfo->bWriteProtected;
|
||||||
|
|
||||||
return eIMAGE_ERROR_NONE;
|
return eIMAGE_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +189,36 @@ void ImageWriteTrack( const HIMAGE hDiskImage,
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
bool ImageReadBlock( const HIMAGE hDiskImage,
|
||||||
|
UINT nBlock,
|
||||||
|
LPBYTE pBlockBuffer)
|
||||||
|
{
|
||||||
|
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||||
|
|
||||||
|
bool bRes = false;
|
||||||
|
if (ptr->pImageType->AllowRW())
|
||||||
|
bRes = ptr->pImageType->Read(ptr, nBlock, pBlockBuffer);
|
||||||
|
|
||||||
|
return bRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool ImageWriteBlock( const HIMAGE hDiskImage,
|
||||||
|
UINT nBlock,
|
||||||
|
LPBYTE pBlockBuffer)
|
||||||
|
{
|
||||||
|
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||||
|
|
||||||
|
bool bRes = false;
|
||||||
|
if (ptr->pImageType->AllowRW() && !ptr->bWriteProtected)
|
||||||
|
bRes = ptr->pImageType->Write(ptr, nBlock, pBlockBuffer);
|
||||||
|
|
||||||
|
return bRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
int ImageGetNumTracks(const HIMAGE hDiskImage)
|
int ImageGetNumTracks(const HIMAGE hDiskImage)
|
||||||
{
|
{
|
||||||
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||||
|
@ -202,3 +236,60 @@ bool ImageIsMultiFileZip(const HIMAGE hDiskImage)
|
||||||
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||||
return ptr ? (ptr->uNumEntriesInZip > 1) : false;
|
return ptr ? (ptr->uNumEntriesInZip > 1) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* ImageGetPathname(const HIMAGE hDiskImage)
|
||||||
|
{
|
||||||
|
static char* szEmpty = "";
|
||||||
|
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||||
|
return ptr ? ptr->szFilename : szEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT ImageGetImageSize(const HIMAGE hDiskImage)
|
||||||
|
{
|
||||||
|
ImageInfo* ptr = (ImageInfo*) hDiskImage;
|
||||||
|
return ptr ? ptr->uImageSize : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetImageTitle(LPCTSTR pPathname, TCHAR* pImageName, TCHAR* pFullName)
|
||||||
|
{
|
||||||
|
TCHAR imagetitle[ MAX_DISK_FULL_NAME+1 ];
|
||||||
|
LPCTSTR startpos = pPathname;
|
||||||
|
|
||||||
|
// imagetitle = <FILENAME.EXT>
|
||||||
|
if (_tcsrchr(startpos, TEXT('\\')))
|
||||||
|
startpos = _tcsrchr(startpos, TEXT('\\'))+1;
|
||||||
|
|
||||||
|
_tcsncpy(imagetitle, startpos, MAX_DISK_FULL_NAME);
|
||||||
|
imagetitle[MAX_DISK_FULL_NAME] = 0;
|
||||||
|
|
||||||
|
// if imagetitle contains a lowercase char, then found=1 (why?)
|
||||||
|
BOOL found = 0;
|
||||||
|
int loop = 0;
|
||||||
|
while (imagetitle[loop] && !found)
|
||||||
|
{
|
||||||
|
if (IsCharLower(imagetitle[loop]))
|
||||||
|
found = 1;
|
||||||
|
else
|
||||||
|
loop++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!found) && (loop > 2))
|
||||||
|
CharLowerBuff(imagetitle+1, _tcslen(imagetitle+1));
|
||||||
|
|
||||||
|
// pFullName = <FILENAME.EXT>
|
||||||
|
_tcsncpy( pFullName, imagetitle, MAX_DISK_FULL_NAME );
|
||||||
|
pFullName[ MAX_DISK_FULL_NAME ] = 0;
|
||||||
|
|
||||||
|
if (imagetitle[0])
|
||||||
|
{
|
||||||
|
LPTSTR dot = imagetitle;
|
||||||
|
if (_tcsrchr(dot, TEXT('.')))
|
||||||
|
dot = _tcsrchr(dot, TEXT('.'));
|
||||||
|
if (dot > imagetitle)
|
||||||
|
*dot = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pImageName = <FILENAME> (ie. no extension)
|
||||||
|
_tcsncpy( pImageName, imagetitle, MAX_DISK_IMAGE_NAME );
|
||||||
|
pImageName[ MAX_DISK_IMAGE_NAME ] = 0;
|
||||||
|
}
|
||||||
|
|
|
@ -55,9 +55,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
eIMAGE_ERROR_UNABLE_TO_OPEN,
|
eIMAGE_ERROR_UNABLE_TO_OPEN,
|
||||||
eIMAGE_ERROR_UNABLE_TO_OPEN_GZ,
|
eIMAGE_ERROR_UNABLE_TO_OPEN_GZ,
|
||||||
eIMAGE_ERROR_UNABLE_TO_OPEN_ZIP,
|
eIMAGE_ERROR_UNABLE_TO_OPEN_ZIP,
|
||||||
|
eIMAGE_ERROR_FAILED_TO_GET_PATHNAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageError_e ImageOpen(LPCTSTR pszImageFilename, HIMAGE* hDiskImage_, bool* pWriteProtected_, const bool bCreateIfNecessary, std::string& strFilenameInZip);
|
const int MAX_DISK_IMAGE_NAME = 15;
|
||||||
|
const int MAX_DISK_FULL_NAME = 127;
|
||||||
|
|
||||||
|
|
||||||
|
ImageError_e ImageOpen(LPCTSTR pszImageFilename, HIMAGE* hDiskImage, bool* pWriteProtected, const bool bCreateIfNecessary, std::string& strFilenameInZip, const bool bExpectFloppy=true);
|
||||||
void ImageClose(const HIMAGE hDiskImage, const bool bOpenError=false);
|
void ImageClose(const HIMAGE hDiskImage, const bool bOpenError=false);
|
||||||
BOOL ImageBoot(const HIMAGE hDiskImage);
|
BOOL ImageBoot(const HIMAGE hDiskImage);
|
||||||
void ImageDestroy(void);
|
void ImageDestroy(void);
|
||||||
|
@ -65,7 +70,13 @@ void ImageInitialize(void);
|
||||||
|
|
||||||
void ImageReadTrack(const HIMAGE hDiskImage, int nTrack, int nQuarterTrack, LPBYTE pTrackImageBuffer, int* pNibbles);
|
void ImageReadTrack(const HIMAGE hDiskImage, int nTrack, int nQuarterTrack, LPBYTE pTrackImageBuffer, int* pNibbles);
|
||||||
void ImageWriteTrack(const HIMAGE hDiskImage, int nTrack, int nQuarterTrack, LPBYTE pTrackImage, int nNibbles);
|
void ImageWriteTrack(const HIMAGE hDiskImage, int nTrack, int nQuarterTrack, LPBYTE pTrackImage, int nNibbles);
|
||||||
|
bool ImageReadBlock(const HIMAGE hDiskImage, UINT nBlock, LPBYTE pBlockBuffer);
|
||||||
|
bool ImageWriteBlock(const HIMAGE hDiskImage, UINT nBlock, LPBYTE pBlockBuffer);
|
||||||
|
|
||||||
int ImageGetNumTracks(const HIMAGE hDiskImage);
|
int ImageGetNumTracks(const HIMAGE hDiskImage);
|
||||||
bool ImageIsWriteProtected(const HIMAGE hDiskImage);
|
bool ImageIsWriteProtected(const HIMAGE hDiskImage);
|
||||||
bool ImageIsMultiFileZip(const HIMAGE hDiskImage);
|
bool ImageIsMultiFileZip(const HIMAGE hDiskImage);
|
||||||
|
const char* ImageGetPathname(const HIMAGE hDiskImage);
|
||||||
|
UINT ImageGetImageSize(const HIMAGE hDiskImage);
|
||||||
|
|
||||||
|
void GetImageTitle(LPCTSTR pPathname, TCHAR* pImageName, TCHAR* pFullName);
|
||||||
|
|
|
@ -28,7 +28,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Structs.h"
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
@ -436,7 +435,7 @@ void CImageBase::DenibblizeTrack(LPBYTE trackimage, SectorOrder_e SectorOrder, i
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((bytenum == 3) && (byteval[1] = 0xAA))
|
if ((bytenum == 3) && (byteval[1] == 0xAA))
|
||||||
{
|
{
|
||||||
int loop = 0;
|
int loop = 0;
|
||||||
int tempoffset = offset;
|
int tempoffset = offset;
|
||||||
|
@ -1435,7 +1434,9 @@ ImageError_e CImageHelperBase::Open( LPCTSTR pszImageFilename,
|
||||||
if (Err != eIMAGE_ERROR_NONE)
|
if (Err != eIMAGE_ERROR_NONE)
|
||||||
return Err;
|
return Err;
|
||||||
|
|
||||||
_tcsncpy(pImageInfo->szFilename, pszImageFilename, MAX_PATH);
|
DWORD uNameLen = GetFullPathName(pszImageFilename, MAX_PATH, pImageInfo->szFilename, NULL);
|
||||||
|
if (uNameLen == 0 || uNameLen >= MAX_PATH)
|
||||||
|
Err = eIMAGE_ERROR_FAILED_TO_GET_PATHNAME;
|
||||||
|
|
||||||
return eIMAGE_ERROR_NONE;
|
return eIMAGE_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -1453,9 +1454,10 @@ void CImageHelperBase::Close(ImageInfo* pImageInfo, const bool bDeleteFile)
|
||||||
if (bDeleteFile)
|
if (bDeleteFile)
|
||||||
{
|
{
|
||||||
DeleteFile(pImageInfo->szFilename);
|
DeleteFile(pImageInfo->szFilename);
|
||||||
pImageInfo->szFilename[0] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pImageInfo->szFilename[0] = 0;
|
||||||
|
|
||||||
delete [] pImageInfo->pImageBuffer;
|
delete [] pImageInfo->pImageBuffer;
|
||||||
pImageInfo->pImageBuffer = NULL;
|
pImageInfo->pImageBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Mockingboard.h"
|
#include "Mockingboard.h"
|
||||||
#include "MouseInterface.h"
|
#include "MouseInterface.h"
|
||||||
#include "ParallelPrinter.h"
|
#include "ParallelPrinter.h"
|
||||||
|
#include "Pravets.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
#include "SaveState.h"
|
#include "SaveState.h"
|
||||||
#include "SerialComms.h"
|
#include "SerialComms.h"
|
||||||
|
@ -183,7 +184,7 @@ static bool g_bFullScreen32Bit = true;
|
||||||
|
|
||||||
// Updates g_pAppTitle
|
// Updates g_pAppTitle
|
||||||
// ====================================================================
|
// ====================================================================
|
||||||
void GetAppleWindowTitle()
|
static void GetAppleWindowTitle()
|
||||||
{
|
{
|
||||||
g_pAppTitle = g_pAppleWindowTitle;
|
g_pAppTitle = g_pAppleWindowTitle;
|
||||||
|
|
||||||
|
@ -568,6 +569,7 @@ static void DrawFrameWindow ()
|
||||||
DebugDisplay(1);
|
DebugDisplay(1);
|
||||||
else
|
else
|
||||||
// Win7: In fullscreen mode with 1 redraw the screen doesn't get redrawn.
|
// Win7: In fullscreen mode with 1 redraw the screen doesn't get redrawn.
|
||||||
|
// TC: 07/01/2015: Tryed with MP's double-buffered DX full-screen code, but still the same.
|
||||||
//VideoRedrawScreen(g_bIsFullScreen ? 2 : 1); // TC: 22/06/2014: Why 2 redraws in full-screen mode (32-bit only)? (8-bit doesn't need this nor does Win8, just Win7 or older OS's)
|
//VideoRedrawScreen(g_bIsFullScreen ? 2 : 1); // TC: 22/06/2014: Why 2 redraws in full-screen mode (32-bit only)? (8-bit doesn't need this nor does Win8, just Win7 or older OS's)
|
||||||
//VideoRefreshScreen(0);
|
//VideoRefreshScreen(0);
|
||||||
VideoRedrawScreen();
|
VideoRedrawScreen();
|
||||||
|
@ -622,6 +624,9 @@ void FrameDrawDiskLEDS( HDC passdc )
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void FrameDrawDiskStatus( HDC passdc )
|
void FrameDrawDiskStatus( HDC passdc )
|
||||||
{
|
{
|
||||||
|
if (mem == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
// We use the actual drive since probing from memory doesn't tell us anything we don't already know.
|
// We use the actual drive since probing from memory doesn't tell us anything we don't already know.
|
||||||
// DOS3.3 ProDOS
|
// DOS3.3 ProDOS
|
||||||
// Drive $B7EA $BE3D
|
// Drive $B7EA $BE3D
|
||||||
|
@ -764,6 +769,14 @@ void FrameDrawDiskStatus( HDC passdc )
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
static void DrawStatusArea (HDC passdc, int drawflags)
|
static void DrawStatusArea (HDC passdc, int drawflags)
|
||||||
{
|
{
|
||||||
|
if (g_hFrameWindow == NULL)
|
||||||
|
{
|
||||||
|
// TC: Fix drawing of drive buttons before frame created:
|
||||||
|
// . Main init loop: LoadConfiguration() called before FrameCreateWindow(), eg:
|
||||||
|
// LoadConfiguration() -> Disk_LoadLastDiskImage() -> DiskInsert() -> FrameRefreshStatus()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FrameReleaseDC();
|
FrameReleaseDC();
|
||||||
HDC dc = (passdc ? passdc : GetDC(g_hFrameWindow));
|
HDC dc = (passdc ? passdc : GetDC(g_hFrameWindow));
|
||||||
int x = buttonx;
|
int x = buttonx;
|
||||||
|
@ -1025,7 +1038,7 @@ LRESULT CALLBACK FrameWndProc (
|
||||||
if (!restart) {
|
if (!restart) {
|
||||||
DiskDestroy();
|
DiskDestroy();
|
||||||
ImageDestroy();
|
ImageDestroy();
|
||||||
HD_Cleanup();
|
HD_Destroy();
|
||||||
}
|
}
|
||||||
PrintDestroy();
|
PrintDestroy();
|
||||||
sg_SSC.CommDestroy();
|
sg_SSC.CommDestroy();
|
||||||
|
@ -1314,7 +1327,7 @@ LRESULT CALLBACK FrameWndProc (
|
||||||
{
|
{
|
||||||
RevealCursor();
|
RevealCursor();
|
||||||
}
|
}
|
||||||
else if (g_nAppMode == MODE_RUNNING)
|
else if (g_nAppMode == MODE_RUNNING || g_nAppMode == MODE_STEPPING)
|
||||||
{
|
{
|
||||||
if (!sg_Mouse.IsEnabled())
|
if (!sg_Mouse.IsEnabled())
|
||||||
{
|
{
|
||||||
|
@ -1391,7 +1404,7 @@ LRESULT CALLBACK FrameWndProc (
|
||||||
DrawCrosshairs(x,y);
|
DrawCrosshairs(x,y);
|
||||||
JoySetPosition(x-viewportx-2, g_nViewportCX-4, y-viewporty-2, g_nViewportCY-4);
|
JoySetPosition(x-viewportx-2, g_nViewportCX-4, y-viewporty-2, g_nViewportCY-4);
|
||||||
}
|
}
|
||||||
else if (sg_Mouse.IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING))
|
else if (sg_Mouse.IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING || g_nAppMode == MODE_STEPPING))
|
||||||
{
|
{
|
||||||
if (g_bLastCursorInAppleViewport)
|
if (g_bLastCursorInAppleViewport)
|
||||||
break;
|
break;
|
||||||
|
@ -1422,7 +1435,7 @@ LRESULT CALLBACK FrameWndProc (
|
||||||
if (wparam == IDEVENT_TIMER_MOUSE)
|
if (wparam == IDEVENT_TIMER_MOUSE)
|
||||||
{
|
{
|
||||||
// NB. Need to check /g_bAppActive/ since WM_TIMER events still occur after AppleWin app has lost focus
|
// NB. Need to check /g_bAppActive/ since WM_TIMER events still occur after AppleWin app has lost focus
|
||||||
if (g_bAppActive && sg_Mouse.IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING))
|
if (g_bAppActive && sg_Mouse.IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING || g_nAppMode == MODE_STEPPING))
|
||||||
{
|
{
|
||||||
if (!g_bLastCursorInAppleViewport)
|
if (!g_bLastCursorInAppleViewport)
|
||||||
break;
|
break;
|
||||||
|
@ -1973,12 +1986,15 @@ void RelayEvent (UINT message, WPARAM wparam, LPARAM lparam) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
// todo: consolidate CtrlReset() and ResetMachineState()
|
||||||
void ResetMachineState ()
|
void ResetMachineState ()
|
||||||
{
|
{
|
||||||
DiskReset(); // Set floppymotoron=0
|
DiskReset(); // Set floppymotoron=0
|
||||||
g_bFullSpeed = 0; // Might've hit reset in middle of InternalCpuExecute() - so beep may get (partially) muted
|
g_bFullSpeed = 0; // Might've hit reset in middle of InternalCpuExecute() - so beep may get (partially) muted
|
||||||
|
|
||||||
MemReset();
|
MemReset();
|
||||||
|
PravetsReset();
|
||||||
DiskBoot();
|
DiskBoot();
|
||||||
VideoResetState();
|
VideoResetState();
|
||||||
sg_SSC.CommReset();
|
sg_SSC.CommReset();
|
||||||
|
@ -1987,7 +2003,7 @@ void ResetMachineState ()
|
||||||
MB_Reset();
|
MB_Reset();
|
||||||
SpkrReset();
|
SpkrReset();
|
||||||
sg_Mouse.Reset();
|
sg_Mouse.Reset();
|
||||||
g_ActiveCPU = CPU_6502;
|
SetActiveCpu( GetMainCpu() );
|
||||||
#ifdef USE_SPEECH_API
|
#ifdef USE_SPEECH_API
|
||||||
g_Speech.Reset();
|
g_Speech.Reset();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1997,12 +2013,15 @@ void ResetMachineState ()
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
// todo: consolidate CtrlReset() and ResetMachineState()
|
||||||
void CtrlReset()
|
void CtrlReset()
|
||||||
{
|
{
|
||||||
// Ctrl+Reset - TODO: This is a terrible place for this code!
|
// Ctrl+Reset - TODO: This is a terrible place for this code!
|
||||||
if (!IS_APPLE2)
|
if (!IS_APPLE2)
|
||||||
MemResetPaging();
|
MemResetPaging();
|
||||||
|
|
||||||
|
PravetsReset();
|
||||||
DiskReset();
|
DiskReset();
|
||||||
KeybReset();
|
KeybReset();
|
||||||
if (!IS_APPLE2)
|
if (!IS_APPLE2)
|
||||||
|
@ -2468,7 +2487,6 @@ void FrameSetCursorPosByMousePos()
|
||||||
int iY, iMinY, iMaxY;
|
int iY, iMinY, iMaxY;
|
||||||
sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY);
|
sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY);
|
||||||
|
|
||||||
_ASSERT(iMinX == 0 && iMinY == 0);
|
|
||||||
float fScaleX = (float)(iX-iMinX) / ((float)(iMaxX-iMinX));
|
float fScaleX = (float)(iX-iMinX) / ((float)(iMaxX-iMinX));
|
||||||
float fScaleY = (float)(iY-iMinY) / ((float)(iMaxY-iMinY));
|
float fScaleY = (float)(iY-iMinY) / ((float)(iMaxY-iMinY));
|
||||||
|
|
||||||
|
@ -2504,7 +2522,6 @@ static void FrameSetCursorPosByMousePos(int x, int y, int dx, int dy, bool bLeav
|
||||||
int iX, iMinX, iMaxX;
|
int iX, iMinX, iMaxX;
|
||||||
int iY, iMinY, iMaxY;
|
int iY, iMinY, iMaxY;
|
||||||
sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY);
|
sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY);
|
||||||
_ASSERT(iMinX == 0 && iMinY == 0);
|
|
||||||
|
|
||||||
if (bLeavingAppleScreen)
|
if (bLeavingAppleScreen)
|
||||||
{
|
{
|
||||||
|
@ -2624,3 +2641,17 @@ void GetViewportCXCY(int& nViewportCX, int& nViewportCY)
|
||||||
nViewportCX = g_nViewportCX;
|
nViewportCX = g_nViewportCX;
|
||||||
nViewportCY = g_nViewportCY;
|
nViewportCY = g_nViewportCY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call all funcs with dependency on g_Apple2Type
|
||||||
|
void FrameUpdateApple2Type(void)
|
||||||
|
{
|
||||||
|
DeleteGdiObjects();
|
||||||
|
CreateGdiObjects();
|
||||||
|
|
||||||
|
// DRAW_TITLE : calls GetAppleWindowTitle()
|
||||||
|
// DRAW_LEDS : update LEDs (eg. CapsLock varies on Apple2 type)
|
||||||
|
DrawStatusArea( (HDC)0, DRAW_TITLE|DRAW_LEDS );
|
||||||
|
|
||||||
|
// Draw buttons & call DrawStatusArea(DRAW_BACKGROUND | DRAW_LEDS | DRAW_DISK_STATUS)
|
||||||
|
DrawFrameWindow();
|
||||||
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
void GetViewportCXCY(int& nViewportCX, int& nViewportCY);
|
void GetViewportCXCY(int& nViewportCX, int& nViewportCY);
|
||||||
bool GetFullScreen32Bit(void);
|
bool GetFullScreen32Bit(void);
|
||||||
void SetFullScreen32Bit(bool b32Bit);
|
void SetFullScreen32Bit(bool b32Bit);
|
||||||
|
void FrameUpdateApple2Type(void);
|
||||||
|
|
||||||
void FrameDrawDiskLEDS( HDC hdc );
|
void FrameDrawDiskLEDS( HDC hdc );
|
||||||
void FrameDrawDiskStatus( HDC hdc );
|
void FrameDrawDiskStatus( HDC hdc );
|
||||||
|
|
|
@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows
|
||||||
Copyright (C) 1994-1996, Michael O'Brien
|
Copyright (C) 1994-1996, Michael O'Brien
|
||||||
Copyright (C) 1999-2001, Oliver Schmidt
|
Copyright (C) 1999-2001, Oliver Schmidt
|
||||||
Copyright (C) 2002-2005, Tom Charlesworth
|
Copyright (C) 2002-2005, Tom Charlesworth
|
||||||
Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
|
Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski
|
||||||
|
|
||||||
AppleWin is free software; you can redistribute it and/or modify
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "HardDisk.h"
|
#include "HardDisk.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#include "..\resource\resource.h"
|
#include "..\resource\resource.h"
|
||||||
|
|
||||||
|
@ -114,28 +115,29 @@ Overview
|
||||||
struct HDD
|
struct HDD
|
||||||
{
|
{
|
||||||
// From Disk_t
|
// From Disk_t
|
||||||
TCHAR imagename[16]; // Not used
|
TCHAR imagename[ MAX_DISK_IMAGE_NAME + 1 ]; // <FILENAME> (ie. no extension) [not used]
|
||||||
TCHAR fullname[128];
|
TCHAR fullname[ MAX_DISK_FULL_NAME + 1 ]; // <FILENAME.EXT> or <FILENAME.zip>
|
||||||
|
std::string strFilenameInZip; // "" or <FILENAME.EXT> [not used]
|
||||||
|
HIMAGE imagehandle; // Init'd by HD_Insert() -> ImageOpen()
|
||||||
|
bool bWriteProtected; // Needed for ImageOpen() [otherwise not used]
|
||||||
//
|
//
|
||||||
BYTE hd_error;
|
BYTE hd_error;
|
||||||
WORD hd_memblock;
|
WORD hd_memblock;
|
||||||
UINT hd_diskblock;
|
UINT hd_diskblock;
|
||||||
WORD hd_buf_ptr;
|
WORD hd_buf_ptr;
|
||||||
BOOL hd_imageloaded;
|
bool hd_imageloaded;
|
||||||
BYTE hd_buf[HD_BLOCK_SIZE+1]; // Why +1?
|
BYTE hd_buf[HD_BLOCK_SIZE+1]; // Why +1? Probably for erroreous reads beyond the block size (ie. reads from I/O addr 0xC0F8)
|
||||||
|
|
||||||
#if HD_LED
|
#if HD_LED
|
||||||
Disk_Status_e hd_status_next;
|
Disk_Status_e hd_status_next;
|
||||||
Disk_Status_e hd_status_prev;
|
Disk_Status_e hd_status_prev;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImageInfo Info;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool g_bHD_RomLoaded = false;
|
static bool g_bHD_RomLoaded = false;
|
||||||
static bool g_bHD_Enabled = false;
|
static bool g_bHD_Enabled = false;
|
||||||
|
|
||||||
static BYTE g_nHD_UnitNum = HARDDISK_1;
|
static BYTE g_nHD_UnitNum = HARDDISK_1<<7; // b7=unit
|
||||||
|
|
||||||
// The HDD interface has a single Command register for both drives:
|
// The HDD interface has a single Command register for both drives:
|
||||||
// . ProDOS will write to Command before switching drives
|
// . ProDOS will write to Command before switching drives
|
||||||
|
@ -143,114 +145,96 @@ static BYTE g_nHD_Command;
|
||||||
|
|
||||||
static HDD g_HardDisk[NUM_HARDDISKS] = {0};
|
static HDD g_HardDisk[NUM_HARDDISKS] = {0};
|
||||||
|
|
||||||
|
static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry
|
||||||
static UINT g_uSlot = 7;
|
static UINT g_uSlot = 7;
|
||||||
|
|
||||||
static CHardDiskImageHelper sg_HardDiskImageHelper;
|
static CHardDiskImageHelper sg_HardDiskImageHelper;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
static void HD_SaveLastDiskImage(const int iDrive);
|
||||||
|
|
||||||
static void HD_CleanupDrive(const int iDrive)
|
static void HD_CleanupDrive(const int iDrive)
|
||||||
{
|
{
|
||||||
sg_HardDiskImageHelper.Close(&g_HardDisk[iDrive].Info, false);
|
if (g_HardDisk[iDrive].imagehandle)
|
||||||
|
|
||||||
g_HardDisk[iDrive].hd_imageloaded = false;
|
|
||||||
g_HardDisk[iDrive].imagename[0] = 0;
|
|
||||||
g_HardDisk[iDrive].fullname[0] = 0;
|
|
||||||
g_HardDisk[iDrive].Info.szFilename[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImageError_e ImageOpen( LPCTSTR pszImageFilename,
|
|
||||||
const int iDrive,
|
|
||||||
const bool bCreateIfNecessary,
|
|
||||||
std::string& strFilenameInZip)
|
|
||||||
{
|
|
||||||
if (!pszImageFilename)
|
|
||||||
return eIMAGE_ERROR_BAD_POINTER;
|
|
||||||
|
|
||||||
HDD* pHDD = &g_HardDisk[iDrive];
|
|
||||||
ImageInfo* pImageInfo = &pHDD->Info;
|
|
||||||
pImageInfo->bWriteProtected = false;
|
|
||||||
|
|
||||||
ImageError_e Err = sg_HardDiskImageHelper.Open(pszImageFilename, pImageInfo, bCreateIfNecessary, strFilenameInZip);
|
|
||||||
|
|
||||||
if (Err != eIMAGE_ERROR_NONE)
|
|
||||||
{
|
{
|
||||||
HD_CleanupDrive(iDrive);
|
ImageClose(g_HardDisk[iDrive].imagehandle);
|
||||||
return Err;
|
g_HardDisk[iDrive].imagehandle = (HIMAGE)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return eIMAGE_ERROR_NONE;
|
g_HardDisk[iDrive].hd_imageloaded = false;
|
||||||
|
|
||||||
|
g_HardDisk[iDrive].imagename[0] = 0;
|
||||||
|
g_HardDisk[iDrive].fullname[0] = 0;
|
||||||
|
g_HardDisk[iDrive].strFilenameInZip = "";
|
||||||
|
|
||||||
|
HD_SaveLastDiskImage(iDrive);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
static void GetImageTitle(LPCTSTR pszImageFilename, HDD* pHardDrive)
|
|
||||||
{
|
|
||||||
TCHAR imagetitle[128];
|
|
||||||
LPCTSTR startpos = pszImageFilename;
|
|
||||||
|
|
||||||
// imagetitle = <FILENAME.EXT>
|
|
||||||
if (_tcsrchr(startpos,TEXT('\\')))
|
|
||||||
startpos = _tcsrchr(startpos,TEXT('\\'))+1;
|
|
||||||
_tcsncpy(imagetitle,startpos,127);
|
|
||||||
imagetitle[127] = 0;
|
|
||||||
|
|
||||||
// if imagetitle contains a lowercase char, then found=1 (why?)
|
|
||||||
BOOL found = 0;
|
|
||||||
int loop = 0;
|
|
||||||
while (imagetitle[loop] && !found)
|
|
||||||
{
|
|
||||||
if (IsCharLower(imagetitle[loop]))
|
|
||||||
found = 1;
|
|
||||||
else
|
|
||||||
loop++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!found) && (loop > 2))
|
|
||||||
CharLowerBuff(imagetitle+1,_tcslen(imagetitle+1));
|
|
||||||
|
|
||||||
// hdptr->fullname = <FILENAME.EXT>
|
|
||||||
_tcsncpy(pHardDrive->fullname,imagetitle,127);
|
|
||||||
pHardDrive->fullname[127] = 0;
|
|
||||||
|
|
||||||
if (imagetitle[0])
|
|
||||||
{
|
|
||||||
LPTSTR dot = imagetitle;
|
|
||||||
if (_tcsrchr(dot,TEXT('.')))
|
|
||||||
dot = _tcsrchr(dot,TEXT('.'));
|
|
||||||
if (dot > imagetitle)
|
|
||||||
*dot = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// hdptr->imagename = <FILENAME> (ie. no extension)
|
|
||||||
_tcsncpy(pHardDrive->imagename,imagetitle,15);
|
|
||||||
pHardDrive->imagename[15] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void NotifyInvalidImage(TCHAR* pszImageFilename)
|
static void NotifyInvalidImage(TCHAR* pszImageFilename)
|
||||||
{
|
{
|
||||||
// TC: TO DO
|
// TC: TO DO
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL HD_Load_Image(const int iDrive, LPCSTR pszImageFilename)
|
//===========================================================================
|
||||||
|
|
||||||
|
BOOL HD_Insert(const int iDrive, LPCTSTR pszImageFilename);
|
||||||
|
|
||||||
|
void HD_LoadLastDiskImage(const int iDrive)
|
||||||
{
|
{
|
||||||
const bool bCreateIfNecessary = false; // NB. Don't allow creation of HDV files
|
_ASSERT(iDrive == HARDDISK_1 || iDrive == HARDDISK_2);
|
||||||
std::string strFilenameInZip; // TODO: Use this
|
|
||||||
ImageError_e Error = ImageOpen(pszImageFilename, iDrive, bCreateIfNecessary, strFilenameInZip);
|
|
||||||
|
|
||||||
g_HardDisk[iDrive].hd_imageloaded = (Error == eIMAGE_ERROR_NONE);
|
char sFilePath[ MAX_PATH + 1];
|
||||||
|
sFilePath[0] = 0;
|
||||||
|
|
||||||
#if HD_LED
|
char *pRegKey = (iDrive == HARDDISK_1)
|
||||||
g_HardDisk[iDrive].hd_status_next = DISK_STATUS_OFF;
|
? REGVALUE_PREF_LAST_HARDDISK_1
|
||||||
g_HardDisk[iDrive].hd_status_prev = DISK_STATUS_OFF;
|
: REGVALUE_PREF_LAST_HARDDISK_2;
|
||||||
#endif
|
|
||||||
|
|
||||||
return g_HardDisk[iDrive].hd_imageloaded;
|
if (RegLoadString(TEXT(REG_PREFS), pRegKey, 1, sFilePath, MAX_PATH))
|
||||||
|
{
|
||||||
|
sFilePath[ MAX_PATH ] = 0;
|
||||||
|
|
||||||
|
g_bSaveDiskImage = false;
|
||||||
|
// Pass in ptr to local copy of filepath, since RemoveDisk() sets DiskPathFilename = "" // todo: update comment for HD func
|
||||||
|
HD_Insert(iDrive, sFilePath);
|
||||||
|
g_bSaveDiskImage = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
// everything below is global
|
static void HD_SaveLastDiskImage(const int iDrive)
|
||||||
|
{
|
||||||
|
_ASSERT(iDrive == HARDDISK_1 || iDrive == HARDDISK_2);
|
||||||
|
|
||||||
|
if (!g_bSaveDiskImage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char *pFileName = g_HardDisk[iDrive].fullname;
|
||||||
|
|
||||||
|
if (iDrive == HARDDISK_1)
|
||||||
|
RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_HARDDISK_1, TRUE, pFileName);
|
||||||
|
else
|
||||||
|
RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_HARDDISK_2, TRUE, pFileName);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
char szPathName[MAX_PATH];
|
||||||
|
strcpy(szPathName, HD_GetFullPathName(iDrive));
|
||||||
|
if (_tcsrchr(szPathName, TEXT('\\')))
|
||||||
|
{
|
||||||
|
char* pPathEnd = _tcsrchr(szPathName, TEXT('\\'))+1;
|
||||||
|
*pPathEnd = 0;
|
||||||
|
RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, szPathName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
// (Nearly) everything below is global
|
||||||
|
|
||||||
static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||||
|
|
||||||
|
@ -263,7 +247,8 @@ bool HD_CardIsEnabled(void)
|
||||||
|
|
||||||
// Called by:
|
// Called by:
|
||||||
// . LoadConfiguration() - Done at each restart
|
// . LoadConfiguration() - Done at each restart
|
||||||
// . DiskDlg_OK() - When HD is enabled/disabled on UI
|
// . RestoreCurrentConfig() - Done when Config dialog is cancelled
|
||||||
|
// . Snapshot_LoadState_v2() - Done to default to disabled state
|
||||||
void HD_SetEnabled(const bool bEnabled)
|
void HD_SetEnabled(const bool bEnabled)
|
||||||
{
|
{
|
||||||
if(g_bHD_Enabled == bEnabled)
|
if(g_bHD_Enabled == bEnabled)
|
||||||
|
@ -298,17 +283,17 @@ LPCTSTR HD_GetFullName(const int iDrive)
|
||||||
|
|
||||||
LPCTSTR HD_GetFullPathName(const int iDrive)
|
LPCTSTR HD_GetFullPathName(const int iDrive)
|
||||||
{
|
{
|
||||||
return g_HardDisk[iDrive].Info.szFilename;
|
return ImageGetPathname(g_HardDisk[iDrive].imagehandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LPCTSTR HD_DiskGetBaseName (const int iDrive) // Not used
|
static LPCTSTR HD_DiskGetBaseName(const int iDrive) // Not used
|
||||||
{
|
{
|
||||||
return g_HardDisk[iDrive].imagename;
|
return g_HardDisk[iDrive].imagename;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
VOID HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot)
|
void HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot)
|
||||||
{
|
{
|
||||||
if(!g_bHD_Enabled)
|
if(!g_bHD_Enabled)
|
||||||
return;
|
return;
|
||||||
|
@ -336,46 +321,82 @@ VOID HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot)
|
||||||
RegisterIoHandler(g_uSlot, HD_IO_EMUL, HD_IO_EMUL, NULL, NULL, NULL, NULL);
|
RegisterIoHandler(g_uSlot, HD_IO_EMUL, HD_IO_EMUL, NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID HD_Cleanup(void)
|
void HD_Destroy(void)
|
||||||
{
|
{
|
||||||
for(int i=HARDDISK_1; i<HARDDISK_2; i++)
|
g_bSaveDiskImage = false;
|
||||||
{
|
HD_CleanupDrive(HARDDISK_1);
|
||||||
HD_CleanupDrive(i);
|
|
||||||
}
|
g_bSaveDiskImage = false;
|
||||||
|
HD_CleanupDrive(HARDDISK_2);
|
||||||
|
|
||||||
|
g_bSaveDiskImage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pszImageFilename is qualified with path
|
// pszImageFilename is qualified with path
|
||||||
BOOL HD_InsertDisk(const int iDrive, LPCTSTR pszImageFilename)
|
static BOOL HD_Insert(const int iDrive, LPCTSTR pszImageFilename)
|
||||||
{
|
{
|
||||||
if (*pszImageFilename == 0x00)
|
if (*pszImageFilename == 0x00)
|
||||||
return false;
|
return FALSE;
|
||||||
|
|
||||||
if (g_HardDisk[iDrive].hd_imageloaded)
|
if (g_HardDisk[iDrive].hd_imageloaded)
|
||||||
HD_CleanupDrive(iDrive);
|
HD_Unplug(iDrive);
|
||||||
|
|
||||||
// Check if image is being used by the other HDD, and unplug it in order to be swapped
|
// Check if image is being used by the other HDD, and unplug it in order to be swapped
|
||||||
if (!strcmp(HD_GetFullPathName(!iDrive), pszImageFilename)) {
|
{
|
||||||
|
const char* pszOtherPathname = HD_GetFullPathName(!iDrive);
|
||||||
|
|
||||||
|
char szCurrentPathname[MAX_PATH];
|
||||||
|
DWORD uNameLen = GetFullPathName(pszImageFilename, MAX_PATH, szCurrentPathname, NULL);
|
||||||
|
if (uNameLen == 0 || uNameLen >= MAX_PATH)
|
||||||
|
strcpy_s(szCurrentPathname, MAX_PATH, pszImageFilename);
|
||||||
|
|
||||||
|
if (!strcmp(pszOtherPathname, szCurrentPathname))
|
||||||
|
{
|
||||||
HD_Unplug(!iDrive);
|
HD_Unplug(!iDrive);
|
||||||
|
FrameRefreshStatus(DRAW_LEDS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL bResult = HD_Load_Image(iDrive, pszImageFilename);
|
const bool bCreateIfNecessary = false; // NB. Don't allow creation of HDV files
|
||||||
|
const bool bExpectFloppy = false;
|
||||||
|
ImageError_e Error = ImageOpen(pszImageFilename,
|
||||||
|
&g_HardDisk[iDrive].imagehandle,
|
||||||
|
&g_HardDisk[iDrive].bWriteProtected,
|
||||||
|
bCreateIfNecessary,
|
||||||
|
g_HardDisk[iDrive].strFilenameInZip, // TODO: Use this
|
||||||
|
bExpectFloppy);
|
||||||
|
|
||||||
if (bResult)
|
g_HardDisk[iDrive].hd_imageloaded = (Error == eIMAGE_ERROR_NONE);
|
||||||
GetImageTitle(pszImageFilename, &g_HardDisk[iDrive]);
|
|
||||||
|
|
||||||
return bResult;
|
#if HD_LED
|
||||||
|
g_HardDisk[iDrive].hd_status_next = DISK_STATUS_OFF;
|
||||||
|
g_HardDisk[iDrive].hd_status_prev = DISK_STATUS_OFF;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (Error == eIMAGE_ERROR_NONE)
|
||||||
|
{
|
||||||
|
GetImageTitle(pszImageFilename, g_HardDisk[iDrive].imagename, g_HardDisk[iDrive].fullname);
|
||||||
|
}
|
||||||
|
|
||||||
|
HD_SaveLastDiskImage(iDrive);
|
||||||
|
|
||||||
|
return g_HardDisk[iDrive].hd_imageloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HD_Select(const int iDrive)
|
static bool HD_SelectImage(const int iDrive, LPCSTR pszFilename)
|
||||||
{
|
{
|
||||||
TCHAR directory[MAX_PATH] = TEXT("");
|
TCHAR directory[MAX_PATH] = TEXT("");
|
||||||
TCHAR filename[MAX_PATH] = TEXT("");
|
TCHAR filename[MAX_PATH] = TEXT("");
|
||||||
TCHAR title[40];
|
TCHAR title[40];
|
||||||
|
|
||||||
|
strcpy(filename, pszFilename);
|
||||||
|
|
||||||
RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, directory, MAX_PATH);
|
RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, directory, MAX_PATH);
|
||||||
_tcscpy(title, TEXT("Select HDV Image For HDD "));
|
_tcscpy(title, TEXT("Select HDV Image For HDD "));
|
||||||
_tcscat(title, iDrive ? TEXT("2") : TEXT("1"));
|
_tcscat(title, iDrive ? TEXT("2") : TEXT("1"));
|
||||||
|
|
||||||
|
_ASSERT(sizeof(OPENFILENAME) == sizeof(OPENFILENAME_NT4)); // Required for Win98/ME support (selected by _WIN32_WINNT=0x0400 in stdafx.h)
|
||||||
|
|
||||||
OPENFILENAME ofn;
|
OPENFILENAME ofn;
|
||||||
ZeroMemory(&ofn,sizeof(OPENFILENAME));
|
ZeroMemory(&ofn,sizeof(OPENFILENAME));
|
||||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||||
|
@ -389,22 +410,29 @@ void HD_Select(const int iDrive)
|
||||||
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; // Don't allow creation & hide the read-only checkbox
|
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; // Don't allow creation & hide the read-only checkbox
|
||||||
ofn.lpstrTitle = title;
|
ofn.lpstrTitle = title;
|
||||||
|
|
||||||
|
bool bRes = false;
|
||||||
|
|
||||||
if (GetOpenFileName(&ofn))
|
if (GetOpenFileName(&ofn))
|
||||||
{
|
{
|
||||||
if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension])
|
if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension])
|
||||||
_tcscat(filename,TEXT(".hdv"));
|
_tcscat(filename,TEXT(".hdv"));
|
||||||
|
|
||||||
if (HD_InsertDisk(iDrive, filename))
|
if (HD_Insert(iDrive, filename))
|
||||||
{
|
{
|
||||||
filename[ofn.nFileOffset] = 0;
|
bRes = true;
|
||||||
if (_tcsicmp(directory, filename))
|
|
||||||
RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, filename);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NotifyInvalidImage(filename);
|
NotifyInvalidImage(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return bRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HD_Select(const int iDrive)
|
||||||
|
{
|
||||||
|
HD_SelectImage(iDrive, TEXT(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HD_Unplug(const int iDrive)
|
void HD_Unplug(const int iDrive)
|
||||||
|
@ -415,7 +443,7 @@ void HD_Unplug(const int iDrive)
|
||||||
|
|
||||||
bool HD_IsDriveUnplugged(const int iDrive)
|
bool HD_IsDriveUnplugged(const int iDrive)
|
||||||
{
|
{
|
||||||
return g_HardDisk[iDrive].hd_imageloaded == FALSE;
|
return g_HardDisk[iDrive].hd_imageloaded == false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -450,16 +478,16 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case 0x00: //status
|
case 0x00: //status
|
||||||
if (pHDD->Info.uImageSize == 0)
|
if (ImageGetImageSize(pHDD->imagehandle) == 0)
|
||||||
{
|
{
|
||||||
pHDD->hd_error = 1;
|
pHDD->hd_error = 1;
|
||||||
r = DEVICE_IO_ERROR;
|
r = DEVICE_IO_ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x01: //read
|
case 0x01: //read
|
||||||
if ((pHDD->hd_diskblock * HD_BLOCK_SIZE) < pHDD->Info.uImageSize)
|
if ((pHDD->hd_diskblock * HD_BLOCK_SIZE) < ImageGetImageSize(pHDD->imagehandle))
|
||||||
{
|
{
|
||||||
bool bRes = pHDD->Info.pImageType->Read(&pHDD->Info, pHDD->hd_diskblock, pHDD->hd_buf);
|
bool bRes = ImageReadBlock(pHDD->imagehandle, pHDD->hd_diskblock, pHDD->hd_buf);
|
||||||
if (bRes)
|
if (bRes)
|
||||||
{
|
{
|
||||||
pHDD->hd_error = 0;
|
pHDD->hd_error = 0;
|
||||||
|
@ -484,17 +512,17 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||||
pHDD->hd_status_next = DISK_STATUS_WRITE;
|
pHDD->hd_status_next = DISK_STATUS_WRITE;
|
||||||
#endif
|
#endif
|
||||||
bool bRes = true;
|
bool bRes = true;
|
||||||
const bool bAppendBlocks = (pHDD->hd_diskblock * HD_BLOCK_SIZE) >= pHDD->Info.uImageSize;
|
const bool bAppendBlocks = (pHDD->hd_diskblock * HD_BLOCK_SIZE) >= ImageGetImageSize(pHDD->imagehandle);
|
||||||
|
|
||||||
if (bAppendBlocks)
|
if (bAppendBlocks)
|
||||||
{
|
{
|
||||||
ZeroMemory(pHDD->hd_buf, HD_BLOCK_SIZE);
|
ZeroMemory(pHDD->hd_buf, HD_BLOCK_SIZE);
|
||||||
|
|
||||||
// Inefficient (especially for gzip/zip files!)
|
// Inefficient (especially for gzip/zip files!)
|
||||||
UINT uBlock = pHDD->Info.uImageSize / HD_BLOCK_SIZE;
|
UINT uBlock = ImageGetImageSize(pHDD->imagehandle) / HD_BLOCK_SIZE;
|
||||||
while (uBlock < pHDD->hd_diskblock)
|
while (uBlock < pHDD->hd_diskblock)
|
||||||
{
|
{
|
||||||
bRes = pHDD->Info.pImageType->Write(&pHDD->Info, uBlock++, pHDD->hd_buf);
|
bRes = ImageWriteBlock(pHDD->imagehandle, uBlock++, pHDD->hd_buf);
|
||||||
_ASSERT(bRes);
|
_ASSERT(bRes);
|
||||||
if (!bRes)
|
if (!bRes)
|
||||||
break;
|
break;
|
||||||
|
@ -504,7 +532,7 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||||
MoveMemory(pHDD->hd_buf, mem+pHDD->hd_memblock, HD_BLOCK_SIZE);
|
MoveMemory(pHDD->hd_buf, mem+pHDD->hd_memblock, HD_BLOCK_SIZE);
|
||||||
|
|
||||||
if (bRes)
|
if (bRes)
|
||||||
bRes = pHDD->Info.pImageType->Write(&pHDD->Info, pHDD->hd_diskblock, pHDD->hd_buf);
|
bRes = ImageWriteBlock(pHDD->imagehandle, pHDD->hd_diskblock, pHDD->hd_buf);
|
||||||
|
|
||||||
if (bRes)
|
if (bRes)
|
||||||
{
|
{
|
||||||
|
@ -560,6 +588,7 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||||
break;
|
break;
|
||||||
case 0xF8:
|
case 0xF8:
|
||||||
r = pHDD->hd_buf[pHDD->hd_buf_ptr];
|
r = pHDD->hd_buf[pHDD->hd_buf_ptr];
|
||||||
|
if (pHDD->hd_buf_ptr < sizeof(pHDD->hd_buf)-1)
|
||||||
pHDD->hd_buf_ptr++;
|
pHDD->hd_buf_ptr++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -631,3 +660,156 @@ void HD_GetLightStatus (Disk_Status_e *pDisk1Status_)
|
||||||
*pDisk1Status_ = DISK_STATUS_OFF;
|
*pDisk1Status_ = DISK_STATUS_OFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_CARD_HDD "Generic HDD"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_CURRENT_UNIT "Current Unit"
|
||||||
|
#define SS_YAML_KEY_COMMAND "Command"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_HDDUNIT "Unit"
|
||||||
|
#define SS_YAML_KEY_FILENAME "Filename"
|
||||||
|
#define SS_YAML_KEY_ERROR "Error"
|
||||||
|
#define SS_YAML_KEY_MEMBLOCK "MemBlock"
|
||||||
|
#define SS_YAML_KEY_DISKBLOCK "DiskBlock"
|
||||||
|
#define SS_YAML_KEY_IMAGELOADED "ImageLoaded"
|
||||||
|
#define SS_YAML_KEY_STATUS_NEXT "Status Next"
|
||||||
|
#define SS_YAML_KEY_STATUS_PREV "Status Prev"
|
||||||
|
#define SS_YAML_KEY_BUF_PTR "Buffer Offset"
|
||||||
|
#define SS_YAML_KEY_BUF "Buffer"
|
||||||
|
|
||||||
|
std::string HD_GetSnapshotCardName(void)
|
||||||
|
{
|
||||||
|
static const std::string name(SS_YAML_VALUE_CARD_HDD);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HD_SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label label(yamlSaveHelper, "%s%d:\n", SS_YAML_KEY_HDDUNIT, unit);
|
||||||
|
yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_HardDisk[unit].fullname);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_ERROR, g_HardDisk[unit].hd_error);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_MEMBLOCK, g_HardDisk[unit].hd_memblock);
|
||||||
|
yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_DISKBLOCK, g_HardDisk[unit].hd_diskblock);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_IMAGELOADED, g_HardDisk[unit].hd_imageloaded);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_NEXT, g_HardDisk[unit].hd_status_next);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_PREV, g_HardDisk[unit].hd_status_prev);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_BUF_PTR, g_HardDisk[unit].hd_buf_ptr);
|
||||||
|
|
||||||
|
// New label
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label buffer(yamlSaveHelper, "%s:\n", SS_YAML_KEY_BUF);
|
||||||
|
yamlSaveHelper.SaveMemory(g_HardDisk[unit].hd_buf, HD_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HD_SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
if (!HD_CardIsEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
YamlSaveHelper::Slot slot(yamlSaveHelper, HD_GetSnapshotCardName(), g_uSlot, 1);
|
||||||
|
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
yamlSaveHelper.Save("%s: %d # b7=unit\n", SS_YAML_KEY_CURRENT_UNIT, g_nHD_UnitNum);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_COMMAND, g_nHD_Command);
|
||||||
|
|
||||||
|
HD_SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_1);
|
||||||
|
HD_SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HD_LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit)
|
||||||
|
{
|
||||||
|
std::string hddUnitName = std::string(SS_YAML_KEY_HDDUNIT) + (unit == HARDDISK_1 ? std::string("0") : std::string("1"));
|
||||||
|
if (!yamlLoadHelper.GetSubMap(hddUnitName))
|
||||||
|
throw std::string("Card: Expected key: ") + hddUnitName;
|
||||||
|
|
||||||
|
g_HardDisk[unit].fullname[0] = 0;
|
||||||
|
g_HardDisk[unit].imagename[0] = 0;
|
||||||
|
g_HardDisk[unit].hd_imageloaded = false; // Default to false (until image is successfully loaded below)
|
||||||
|
g_HardDisk[unit].hd_status_next = DISK_STATUS_OFF;
|
||||||
|
g_HardDisk[unit].hd_status_prev = DISK_STATUS_OFF;
|
||||||
|
|
||||||
|
std::string filename = yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME);
|
||||||
|
g_HardDisk[unit].hd_error = yamlLoadHelper.LoadUint(SS_YAML_KEY_ERROR);
|
||||||
|
g_HardDisk[unit].hd_memblock = yamlLoadHelper.LoadUint(SS_YAML_KEY_MEMBLOCK);
|
||||||
|
g_HardDisk[unit].hd_diskblock = yamlLoadHelper.LoadUint(SS_YAML_KEY_DISKBLOCK);
|
||||||
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_IMAGELOADED); // Consume
|
||||||
|
Disk_Status_e diskStatusNext = (Disk_Status_e) yamlLoadHelper.LoadUint(SS_YAML_KEY_STATUS_NEXT);
|
||||||
|
Disk_Status_e diskStatusPrev = (Disk_Status_e) yamlLoadHelper.LoadUint(SS_YAML_KEY_STATUS_PREV);
|
||||||
|
g_HardDisk[unit].hd_buf_ptr = yamlLoadHelper.LoadUint(SS_YAML_KEY_BUF_PTR);
|
||||||
|
|
||||||
|
if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_BUF))
|
||||||
|
throw hddUnitName + std::string(": Missing: ") + std::string(SS_YAML_KEY_BUF);
|
||||||
|
yamlLoadHelper.LoadMemory(g_HardDisk[unit].hd_buf, HD_BLOCK_SIZE);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
bool bResSelectImage = false;
|
||||||
|
|
||||||
|
if (!filename.empty())
|
||||||
|
{
|
||||||
|
DWORD dwAttributes = GetFileAttributes(filename.c_str());
|
||||||
|
if (dwAttributes == INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
// Get user to browse for file
|
||||||
|
bResSelectImage = HD_SelectImage(unit, filename.c_str());
|
||||||
|
|
||||||
|
dwAttributes = GetFileAttributes(filename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES);
|
||||||
|
if (!bImageError)
|
||||||
|
{
|
||||||
|
if (!HD_Insert(unit, filename.c_str()))
|
||||||
|
bImageError = true;
|
||||||
|
|
||||||
|
// HD_Insert() sets up:
|
||||||
|
// . imagename
|
||||||
|
// . fullname
|
||||||
|
// . hd_imageloaded
|
||||||
|
// . hd_status_next = DISK_STATUS_OFF
|
||||||
|
// . hd_status_prev = DISK_STATUS_OFF
|
||||||
|
|
||||||
|
g_HardDisk[unit].hd_status_next = diskStatusNext;
|
||||||
|
g_HardDisk[unit].hd_status_prev = diskStatusPrev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bResSelectImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HD_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, const std::string strSaveStatePath)
|
||||||
|
{
|
||||||
|
if (slot != 7) // fixme
|
||||||
|
throw std::string("Card: wrong slot");
|
||||||
|
|
||||||
|
if (version != 1)
|
||||||
|
throw std::string("Card: wrong version");
|
||||||
|
|
||||||
|
g_nHD_UnitNum = yamlLoadHelper.LoadUint(SS_YAML_KEY_CURRENT_UNIT); // b7=unit
|
||||||
|
g_nHD_Command = yamlLoadHelper.LoadUint(SS_YAML_KEY_COMMAND);
|
||||||
|
|
||||||
|
// Unplug all HDDs first in case HDD-2 is to be plugged in as HDD-1
|
||||||
|
for (UINT i=0; i<NUM_HARDDISKS; i++)
|
||||||
|
{
|
||||||
|
HD_Unplug(i);
|
||||||
|
ZeroMemory(&g_HardDisk[i], sizeof(HDD));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bResSelectImage1 = HD_LoadSnapshotHDDUnit(yamlLoadHelper, HARDDISK_1);
|
||||||
|
bool bResSelectImage2 = HD_LoadSnapshotHDDUnit(yamlLoadHelper, HARDDISK_2);
|
||||||
|
|
||||||
|
if (!bResSelectImage1 && !bResSelectImage2)
|
||||||
|
RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, strSaveStatePath.c_str());
|
||||||
|
|
||||||
|
HD_SetEnabled(true);
|
||||||
|
|
||||||
|
FrameRefreshStatus(DRAW_LEDS);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -30,16 +30,20 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
NUM_HARDDISKS
|
NUM_HARDDISKS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void HD_Destroy(void);
|
||||||
bool HD_CardIsEnabled(void);
|
bool HD_CardIsEnabled(void);
|
||||||
void HD_SetEnabled(const bool bEnabled);
|
void HD_SetEnabled(const bool bEnabled);
|
||||||
LPCTSTR HD_GetFullName(const int iDrive);
|
LPCTSTR HD_GetFullName(const int iDrive);
|
||||||
LPCTSTR HD_GetFullPathName(const int iDrive);
|
LPCTSTR HD_GetFullPathName(const int iDrive);
|
||||||
VOID HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot);
|
void HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot);
|
||||||
VOID HD_Cleanup(void);
|
|
||||||
BOOL HD_InsertDisk(const int iDrive, LPCTSTR pszImageFilename);
|
|
||||||
void HD_Select(const int iDrive);
|
void HD_Select(const int iDrive);
|
||||||
void HD_Unplug(const int iDrive);
|
void HD_Unplug(const int iDrive);
|
||||||
bool HD_IsDriveUnplugged(const int iDrive);
|
bool HD_IsDriveUnplugged(const int iDrive);
|
||||||
|
void HD_LoadLastDiskImage(const int iDrive);
|
||||||
|
|
||||||
// 1.19.0.0 Hard Disk Status/Indicator Light
|
// 1.19.0.0 Hard Disk Status/Indicator Light
|
||||||
void HD_GetLightStatus (Disk_Status_e *pDisk1Status_);
|
void HD_GetLightStatus (Disk_Status_e *pDisk1Status_);
|
||||||
|
|
||||||
|
std::string HD_GetSnapshotCardName(void);
|
||||||
|
void HD_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
bool HD_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, const std::string strSaveStatePath);
|
||||||
|
|
|
@ -42,6 +42,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "AppleWin.h"
|
#include "AppleWin.h"
|
||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#include "Configuration\PropertySheet.h"
|
#include "Configuration\PropertySheet.h"
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ static int joysubx[2] = {0,0};
|
||||||
static int joysuby[2] = {0,0};
|
static int joysuby[2] = {0,0};
|
||||||
|
|
||||||
// Value persisted to Registry for REGVALUE_JOYSTICK0_EMU_TYPE
|
// Value persisted to Registry for REGVALUE_JOYSTICK0_EMU_TYPE
|
||||||
DWORD joytype[2] = {J0C_JOYSTICK1, J1C_DISABLED}; // Emulation Type for joysticks #0 & #1
|
static DWORD joytype[2] = {J0C_JOYSTICK1, J1C_DISABLED}; // Emulation Type for joysticks #0 & #1
|
||||||
|
|
||||||
static BOOL setbutton[3] = {0,0,0}; // Used when a mouse button is pressed/released
|
static BOOL setbutton[3] = {0,0,0}; // Used when a mouse button is pressed/released
|
||||||
|
|
||||||
|
@ -753,6 +754,30 @@ void JoyDisableUsingMouse()
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
void JoySetJoyType(UINT num, DWORD type)
|
||||||
|
{
|
||||||
|
_ASSERT(num <= JN_JOYSTICK1);
|
||||||
|
if (num > JN_JOYSTICK1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
joytype[num] = type;
|
||||||
|
|
||||||
|
// Refresh centre positions whenever 'joytype' changes
|
||||||
|
JoySetTrim(JoyGetTrim(true) , true);
|
||||||
|
JoySetTrim(JoyGetTrim(false), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD JoyGetJoyType(UINT num)
|
||||||
|
{
|
||||||
|
_ASSERT(num <= JN_JOYSTICK1);
|
||||||
|
if (num > JN_JOYSTICK1)
|
||||||
|
return J0C_DISABLED;
|
||||||
|
|
||||||
|
return joytype[num];
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
void JoySetTrim(short nValue, bool bAxisX)
|
void JoySetTrim(short nValue, bool bAxisX)
|
||||||
{
|
{
|
||||||
if(bAxisX)
|
if(bAxisX)
|
||||||
|
@ -824,14 +849,45 @@ void JoyportControl(const UINT uControl)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS)
|
void JoySetSnapshot_v1(const unsigned __int64 JoyCntrResetCycle)
|
||||||
{
|
{
|
||||||
pSS->g_nJoyCntrResetCycle = g_nJoyCntrResetCycle;
|
g_nJoyCntrResetCycle = JoyCntrResetCycle;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD JoySetSnapshot(SS_IO_Joystick* pSS)
|
//
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_COUNTERRESETCYCLE "Counter Reset Cycle"
|
||||||
|
#define SS_YAML_KEY_JOY0TRIMX "Joystick0 TrimX"
|
||||||
|
#define SS_YAML_KEY_JOY0TRIMY "Joystick0 TrimY"
|
||||||
|
#define SS_YAML_KEY_JOY1TRIMX "Joystick1 TrimX"
|
||||||
|
#define SS_YAML_KEY_JOY1TRIMY "Joystick1 TrimY"
|
||||||
|
|
||||||
|
static std::string JoyGetSnapshotStructName(void)
|
||||||
{
|
{
|
||||||
g_nJoyCntrResetCycle = pSS->g_nJoyCntrResetCycle;
|
static const std::string name("Joystick");
|
||||||
return 0;
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoySaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", JoyGetSnapshotStructName().c_str());
|
||||||
|
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_COUNTERRESETCYCLE, g_nJoyCntrResetCycle);
|
||||||
|
yamlSaveHelper.SaveInt(SS_YAML_KEY_JOY0TRIMX, JoyGetTrim(true));
|
||||||
|
yamlSaveHelper.SaveInt(SS_YAML_KEY_JOY0TRIMY, JoyGetTrim(false));
|
||||||
|
yamlSaveHelper.Save("%s: %d # not implemented yet\n", SS_YAML_KEY_JOY1TRIMX, 0); // not implemented yet
|
||||||
|
yamlSaveHelper.Save("%s: %d # not implemented yet\n", SS_YAML_KEY_JOY1TRIMY, 0); // not implemented yet
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoyLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(JoyGetSnapshotStructName()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_nJoyCntrResetCycle = yamlLoadHelper.LoadUint64(SS_YAML_KEY_COUNTERRESETCYCLE);
|
||||||
|
JoySetTrim(yamlLoadHelper.LoadInt(SS_YAML_KEY_JOY0TRIMX), true);
|
||||||
|
JoySetTrim(yamlLoadHelper.LoadInt(SS_YAML_KEY_JOY0TRIMY), false);
|
||||||
|
yamlLoadHelper.LoadInt(SS_YAML_KEY_JOY1TRIMX); // dump value
|
||||||
|
yamlLoadHelper.LoadInt(SS_YAML_KEY_JOY1TRIMY); // dump value
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ enum JOYNUM {JN_JOYSTICK0=0, JN_JOYSTICK1};
|
||||||
enum JOY0CHOICE {J0C_DISABLED=0, J0C_JOYSTICK1, J0C_KEYBD_CURSORS, J0C_KEYBD_NUMPAD, J0C_MOUSE, J0C_MAX};
|
enum JOY0CHOICE {J0C_DISABLED=0, J0C_JOYSTICK1, J0C_KEYBD_CURSORS, J0C_KEYBD_NUMPAD, J0C_MOUSE, J0C_MAX};
|
||||||
enum JOY1CHOICE {J1C_DISABLED=0, J1C_JOYSTICK2, J1C_KEYBD_CURSORS, J1C_KEYBD_NUMPAD, J1C_MOUSE, J1C_MAX};
|
enum JOY1CHOICE {J1C_DISABLED=0, J1C_JOYSTICK2, J1C_KEYBD_CURSORS, J1C_KEYBD_NUMPAD, J1C_MOUSE, J1C_MAX};
|
||||||
|
|
||||||
extern DWORD joytype[2];
|
|
||||||
|
|
||||||
enum {JOYSTICK_MODE_FLOATING=0, JOYSTICK_MODE_CENTERING}; // Joystick centering control
|
enum {JOYSTICK_MODE_FLOATING=0, JOYSTICK_MODE_CENTERING}; // Joystick centering control
|
||||||
|
|
||||||
void JoyInitialize();
|
void JoyInitialize();
|
||||||
|
@ -21,11 +19,14 @@ BOOL JoyUsingKeyboard();
|
||||||
BOOL JoyUsingKeyboardCursors();
|
BOOL JoyUsingKeyboardCursors();
|
||||||
BOOL JoyUsingKeyboardNumpad();
|
BOOL JoyUsingKeyboardNumpad();
|
||||||
void JoyDisableUsingMouse();
|
void JoyDisableUsingMouse();
|
||||||
|
void JoySetJoyType(UINT num, DWORD type);
|
||||||
|
DWORD JoyGetJoyType(UINT num);
|
||||||
void JoySetTrim(short nValue, bool bAxisX);
|
void JoySetTrim(short nValue, bool bAxisX);
|
||||||
short JoyGetTrim(bool bAxisX);
|
short JoyGetTrim(bool bAxisX);
|
||||||
void JoyportControl(const UINT uControl);
|
void JoyportControl(const UINT uControl);
|
||||||
DWORD JoyGetSnapshot(SS_IO_Joystick* pSS);
|
void JoySetSnapshot_v1(const unsigned __int64 JoyCntrResetCycle);
|
||||||
DWORD JoySetSnapshot(SS_IO_Joystick* pSS);
|
void JoySaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
void JoyLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
|
||||||
|
|
||||||
BYTE __stdcall JoyReadButton(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
BYTE __stdcall JoyReadButton(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||||
BYTE __stdcall JoyReadPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
BYTE __stdcall JoyReadPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||||
|
|
|
@ -31,7 +31,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "AppleWin.h"
|
#include "AppleWin.h"
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
|
#include "Pravets.h"
|
||||||
#include "Tape.h"
|
#include "Tape.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
static bool g_bKeybBufferEnable = false;
|
static bool g_bKeybBufferEnable = false;
|
||||||
|
|
||||||
|
@ -50,7 +52,6 @@ static bool g_bCapsLock = true; //Caps lock key for Apple2 and Lat/Cyr lock for
|
||||||
static bool g_bP8CapsLock = true; //Caps lock key of Pravets 8A/C
|
static bool g_bP8CapsLock = true; //Caps lock key of Pravets 8A/C
|
||||||
static int lastvirtkey = 0; // Current PC keycode
|
static int lastvirtkey = 0; // Current PC keycode
|
||||||
static BYTE keycode = 0; // Current Apple keycode
|
static BYTE keycode = 0; // Current Apple keycode
|
||||||
static DWORD keyboardqueries = 0;
|
|
||||||
|
|
||||||
#ifdef KEY_OLD
|
#ifdef KEY_OLD
|
||||||
// Original
|
// Original
|
||||||
|
@ -160,14 +161,6 @@ BYTE KeybGetKeycode () // Used by MemCheckPaging() & VideoCheckMode()
|
||||||
return keycode;
|
return keycode;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
DWORD KeybGetNumQueries () // Used in determining 'idleness' of Apple system
|
|
||||||
{
|
|
||||||
DWORD result = keyboardqueries;
|
|
||||||
keyboardqueries = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void KeybQueueKeypress (int key, BOOL bASCII)
|
void KeybQueueKeypress (int key, BOOL bASCII)
|
||||||
{
|
{
|
||||||
|
@ -425,10 +418,6 @@ static char ClipboardCurrChar(bool bIncPtr)
|
||||||
|
|
||||||
BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG)
|
BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG)
|
||||||
{
|
{
|
||||||
keyboardqueries++;
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
if(g_bPasteFromClipboard)
|
if(g_bPasteFromClipboard)
|
||||||
ClipboardInit();
|
ClipboardInit();
|
||||||
|
|
||||||
|
@ -463,10 +452,6 @@ BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG)
|
||||||
|
|
||||||
BYTE __stdcall KeybReadFlag (WORD, WORD, BYTE, BYTE, ULONG)
|
BYTE __stdcall KeybReadFlag (WORD, WORD, BYTE, BYTE, ULONG)
|
||||||
{
|
{
|
||||||
keyboardqueries++;
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
if(g_bPasteFromClipboard)
|
if(g_bPasteFromClipboard)
|
||||||
ClipboardInit();
|
ClipboardInit();
|
||||||
|
|
||||||
|
@ -516,16 +501,33 @@ void KeybToggleP8ACapsLock ()
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD KeybGetSnapshot(SS_IO_Keyboard* pSS)
|
void KeybSetSnapshot_v1(const BYTE LastKey)
|
||||||
{
|
{
|
||||||
pSS->keyboardqueries = keyboardqueries;
|
g_nLastKey = LastKey;
|
||||||
pSS->nLastKey = g_nLastKey;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD KeybSetSnapshot(SS_IO_Keyboard* pSS)
|
//
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_LASTKEY "Last Key"
|
||||||
|
|
||||||
|
static std::string KeybGetSnapshotStructName(void)
|
||||||
{
|
{
|
||||||
keyboardqueries = pSS->keyboardqueries;
|
static const std::string name("Keyboard");
|
||||||
g_nLastKey = pSS->nLastKey;
|
return name;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
void KeybSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", KeybGetSnapshotStructName().c_str());
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_LASTKEY, g_nLastKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeybLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(KeybGetSnapshotStructName()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_nLastKey = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTKEY);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,12 @@ bool KeybGetShiftStatus();
|
||||||
bool KeybGetCapsAllowed(); //For Pravets8A/C only
|
bool KeybGetCapsAllowed(); //For Pravets8A/C only
|
||||||
void KeybUpdateCtrlShiftStatus();
|
void KeybUpdateCtrlShiftStatus();
|
||||||
BYTE KeybGetKeycode ();
|
BYTE KeybGetKeycode ();
|
||||||
DWORD KeybGetNumQueries ();
|
|
||||||
void KeybQueueKeypress (int,BOOL);
|
void KeybQueueKeypress (int,BOOL);
|
||||||
void KeybToggleCapsLock ();
|
void KeybToggleCapsLock ();
|
||||||
void KeybToggleP8ACapsLock ();
|
void KeybToggleP8ACapsLock ();
|
||||||
DWORD KeybGetSnapshot(SS_IO_Keyboard* pSS);
|
void KeybSetSnapshot_v1(const BYTE LastKey);
|
||||||
DWORD KeybSetSnapshot(SS_IO_Keyboard* pSS);
|
void KeybSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
void KeybLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
|
||||||
|
|
||||||
BYTE __stdcall KeybReadData (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
BYTE __stdcall KeybReadData (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||||
BYTE __stdcall KeybReadFlag (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
BYTE __stdcall KeybReadFlag (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||||
|
|
|
@ -57,5 +57,5 @@ void LogFileOutput(LPCTSTR format, ...)
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
|
||||||
_vsntprintf(output, sizeof(output) - 1, format, args);
|
_vsntprintf(output, sizeof(output) - 1, format, args);
|
||||||
fprintf(g_fh, output);
|
fprintf(g_fh, "%s", output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
/* Description: Memory emulation
|
/* Description: Memory emulation
|
||||||
*
|
*
|
||||||
* Author: Various
|
* Author: Various
|
||||||
|
*
|
||||||
|
* In comments, UTA2E is an abbreviation for a reference to "Understanding the Apple //e" by James Sather
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
@ -42,6 +44,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "NoSlotClock.h"
|
#include "NoSlotClock.h"
|
||||||
#include "ParallelPrinter.h"
|
#include "ParallelPrinter.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
|
#include "SAM.h"
|
||||||
#include "SerialComms.h"
|
#include "SerialComms.h"
|
||||||
#include "Speaker.h"
|
#include "Speaker.h"
|
||||||
#include "Tape.h"
|
#include "Tape.h"
|
||||||
|
@ -52,6 +55,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "..\resource\resource.h"
|
#include "..\resource\resource.h"
|
||||||
#include "Configuration\PropertySheet.h"
|
#include "Configuration\PropertySheet.h"
|
||||||
#include "Debugger\DebugDefs.h"
|
#include "Debugger\DebugDefs.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
// Memory Flag
|
// Memory Flag
|
||||||
#define MF_80STORE 0x00000001
|
#define MF_80STORE 0x00000001
|
||||||
|
@ -170,7 +174,7 @@ iofunction IORead[256];
|
||||||
iofunction IOWrite[256];
|
iofunction IOWrite[256];
|
||||||
static LPVOID SlotParameters[NUM_SLOTS];
|
static LPVOID SlotParameters[NUM_SLOTS];
|
||||||
|
|
||||||
static BOOL lastwriteram = 0;
|
static BOOL lastwriteram = 0; // NB. redundant - only used in MemSetPaging(), where it's forced to 1
|
||||||
|
|
||||||
LPBYTE mem = NULL;
|
LPBYTE mem = NULL;
|
||||||
|
|
||||||
|
@ -194,12 +198,12 @@ static BOOL Pravets8charmode = 0;
|
||||||
static CNoSlotClock g_NoSlotClock;
|
static CNoSlotClock g_NoSlotClock;
|
||||||
|
|
||||||
#ifdef RAMWORKS
|
#ifdef RAMWORKS
|
||||||
UINT g_uMaxExPages = 1; // user requested ram pages
|
UINT g_uMaxExPages = 1; // user requested ram pages (default to 1 aux bank: so total = 128KB)
|
||||||
static LPBYTE RWpages[128]; // pointers to RW memory banks
|
UINT g_uActiveBank = 0; // 0 = aux 64K for: //e extended 80 Col card, or //c
|
||||||
|
static LPBYTE RWpages[kMaxExMemoryBanks]; // pointers to RW memory banks
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
|
BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
|
||||||
void UpdatePaging(BOOL initialize);
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
@ -231,7 +235,7 @@ static BYTE __stdcall IORead_C01x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||||
case 0x6: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x6: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
|
||||||
case 0x7: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x7: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
|
||||||
case 0x8: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x8: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
|
||||||
case 0x9: return VideoCheckVbl( nCyclesLeft ); // NTSC cleanup
|
case 0x9: return VideoCheckVbl(nCyclesLeft);
|
||||||
case 0xA: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xA: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
|
||||||
case 0xB: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xB: return VideoCheckMode(pc, addr, bWrite, d, nCyclesLeft);
|
||||||
case 0xC: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xC: return MemCheckPaging(pc, addr, bWrite, d, nCyclesLeft);
|
||||||
|
@ -342,7 +346,7 @@ static BYTE __stdcall IORead_C06x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||||
{
|
{
|
||||||
static byte CurrentKestroke = 0;
|
static byte CurrentKestroke = 0;
|
||||||
CurrentKestroke = KeybGetKeycode();
|
CurrentKestroke = KeybGetKeycode();
|
||||||
switch (addr & 0xf)
|
switch (addr & 0x7) // address bit 4 is ignored (UTA2E page 7-5)
|
||||||
{
|
{
|
||||||
//In Pravets8A/C if SETMODE (8bit character encoding) is enabled, bit6 in $C060 is 0; Else it is 1
|
//In Pravets8A/C if SETMODE (8bit character encoding) is enabled, bit6 in $C060 is 0; Else it is 1
|
||||||
//If (CAPS lOCK of Pravets8A/C is on or Shift is pressed) and (MODE is enabled), bit7 in $C000 is 1; Else it is 0
|
//If (CAPS lOCK of Pravets8A/C is on or Shift is pressed) and (MODE is enabled), bit7 in $C000 is 1; Else it is 0
|
||||||
|
@ -356,14 +360,6 @@ static BYTE __stdcall IORead_C06x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||||
case 0x5: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft); //$C065 Analog input 1
|
case 0x5: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft); //$C065 Analog input 1
|
||||||
case 0x6: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft); //$C066 Analog input 2
|
case 0x6: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft); //$C066 Analog input 2
|
||||||
case 0x7: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft); //$C067 Analog input 3
|
case 0x7: return JoyReadPosition(pc, addr, bWrite, d, nCyclesLeft); //$C067 Analog input 3
|
||||||
case 0x8: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
|
|
||||||
case 0x9: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
|
|
||||||
case 0xA: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
|
|
||||||
case 0xB: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
|
|
||||||
case 0xC: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
|
|
||||||
case 0xD: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
|
|
||||||
case 0xE: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
|
|
||||||
case 0xF: return IO_Null(pc, addr, bWrite, d, nCyclesLeft);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -694,11 +690,6 @@ static void InitIoHandlers()
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
IO_SELECT = 0;
|
|
||||||
IO_SELECT_InternalROM = 0;
|
|
||||||
g_eExpansionRomType = eExpRomNull;
|
|
||||||
g_uPeripheralRomSlot = 0;
|
|
||||||
|
|
||||||
for (i=0; i<NUM_SLOTS; i++)
|
for (i=0; i<NUM_SLOTS; i++)
|
||||||
{
|
{
|
||||||
g_SlotInfo[i].bHasCard = false;
|
g_SlotInfo[i].bHasCard = false;
|
||||||
|
@ -815,6 +806,16 @@ static void SetMemMode(const DWORD uNewMemMode)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
static void ResetPaging(BOOL initialize);
|
||||||
|
static void UpdatePaging(BOOL initialize);
|
||||||
|
|
||||||
|
// Call by:
|
||||||
|
// . CtrlReset() Soft-reset (Ctrl+Reset)
|
||||||
|
void MemResetPaging()
|
||||||
|
{
|
||||||
|
ResetPaging(0); // Initialize=0
|
||||||
|
}
|
||||||
|
|
||||||
static void ResetPaging(BOOL initialize)
|
static void ResetPaging(BOOL initialize)
|
||||||
{
|
{
|
||||||
lastwriteram = 0;
|
lastwriteram = 0;
|
||||||
|
@ -1028,6 +1029,7 @@ static LPBYTE MemGetPtrBANK1(const WORD offset, const LPBYTE pMemBase)
|
||||||
if ((offset & 0xF000) != 0xC000) // Requesting RAM at physical addr $Cxxx (ie. 4K RAM BANK1)
|
if ((offset & 0xF000) != 0xC000) // Requesting RAM at physical addr $Cxxx (ie. 4K RAM BANK1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// NB. This works for memaux when set to any RWpages[] value, ie. RamWork III "just works"
|
||||||
const BYTE bank1page = (offset >> 8) & 0xF;
|
const BYTE bank1page = (offset >> 8) & 0xF;
|
||||||
return (memshadow[0xD0+bank1page] == pMemBase+(0xC0+bank1page)*256)
|
return (memshadow[0xD0+bank1page] == pMemBase+(0xC0+bank1page)*256)
|
||||||
? mem+offset+0x1000 // Return ptr to $Dxxx address - 'mem' has (a potentially dirty) 4K RAM BANK1 mapped in at $D000
|
? mem+offset+0x1000 // Return ptr to $Dxxx address - 'mem' has (a potentially dirty) 4K RAM BANK1 mapped in at $D000
|
||||||
|
@ -1104,17 +1106,14 @@ LPBYTE MemGetCxRomPeripheral()
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
const UINT CxRomSize = 4*1024;
|
||||||
|
const UINT Apple2RomSize = 12*1024;
|
||||||
|
const UINT Apple2eRomSize = Apple2RomSize+CxRomSize;
|
||||||
|
//const UINT Pravets82RomSize = 12*1024;
|
||||||
|
//const UINT Pravets8ARomSize = Pravets82RomSize+CxRomSize;
|
||||||
|
|
||||||
void MemInitialize()
|
void MemInitialize()
|
||||||
{
|
{
|
||||||
// Init the I/O handlers
|
|
||||||
InitIoHandlers();
|
|
||||||
|
|
||||||
const UINT CxRomSize = 4*1024;
|
|
||||||
const UINT Apple2RomSize = 12*1024;
|
|
||||||
const UINT Apple2eRomSize = Apple2RomSize+CxRomSize;
|
|
||||||
//const UINT Pravets82RomSize = 12*1024;
|
|
||||||
//const UINT Pravets8ARomSize = Pravets82RomSize+CxRomSize;
|
|
||||||
|
|
||||||
// ALLOCATE MEMORY FOR THE APPLE MEMORY IMAGE AND ASSOCIATED DATA STRUCTURES
|
// ALLOCATE MEMORY FOR THE APPLE MEMORY IMAGE AND ASSOCIATED DATA STRUCTURES
|
||||||
memaux = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
|
memaux = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
|
||||||
memmain = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
|
memmain = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
|
||||||
|
@ -1149,12 +1148,22 @@ void MemInitialize()
|
||||||
|
|
||||||
#ifdef RAMWORKS
|
#ifdef RAMWORKS
|
||||||
// allocate memory for RAMWorks III - up to 8MB
|
// allocate memory for RAMWorks III - up to 8MB
|
||||||
RWpages[0] = memaux;
|
g_uActiveBank = 0;
|
||||||
|
RWpages[g_uActiveBank] = memaux;
|
||||||
|
|
||||||
UINT i = 1;
|
UINT i = 1;
|
||||||
while ((i < g_uMaxExPages) && (RWpages[i] = (LPBYTE) VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE)))
|
while ((i < g_uMaxExPages) && (RWpages[i] = (LPBYTE) VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE)))
|
||||||
i++;
|
i++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
MemInitializeROM();
|
||||||
|
MemInitializeCustomF8ROM();
|
||||||
|
MemInitializeIO();
|
||||||
|
MemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemInitializeROM(void)
|
||||||
|
{
|
||||||
// READ THE APPLE FIRMWARE ROMS INTO THE ROM IMAGE
|
// READ THE APPLE FIRMWARE ROMS INTO THE ROM IMAGE
|
||||||
UINT ROM_SIZE = 0;
|
UINT ROM_SIZE = 0;
|
||||||
HRSRC hResInfo = NULL;
|
HRSRC hResInfo = NULL;
|
||||||
|
@ -1211,8 +1220,6 @@ void MemInitialize()
|
||||||
if (pData == NULL)
|
if (pData == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
memset(pCxRomInternal,0,CxRomSize);
|
memset(pCxRomInternal,0,CxRomSize);
|
||||||
memset(pCxRomPeripheral,0,CxRomSize);
|
memset(pCxRomPeripheral,0,CxRomSize);
|
||||||
|
|
||||||
|
@ -1225,16 +1232,22 @@ void MemInitialize()
|
||||||
|
|
||||||
_ASSERT(ROM_SIZE == Apple2RomSize);
|
_ASSERT(ROM_SIZE == Apple2RomSize);
|
||||||
memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF
|
memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemInitializeCustomF8ROM(void)
|
||||||
|
{
|
||||||
const UINT F8RomSize = 0x800;
|
const UINT F8RomSize = 0x800;
|
||||||
if (g_hCustomRomF8 != INVALID_HANDLE_VALUE)
|
if (g_hCustomRomF8 != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
|
BYTE OldRom[Apple2RomSize]; // NB. 12KB on stack
|
||||||
|
memcpy(OldRom, memrom, Apple2RomSize);
|
||||||
|
|
||||||
SetFilePointer(g_hCustomRomF8, 0, NULL, FILE_BEGIN);
|
SetFilePointer(g_hCustomRomF8, 0, NULL, FILE_BEGIN);
|
||||||
DWORD uNumBytesRead;
|
DWORD uNumBytesRead;
|
||||||
BOOL bRes = ReadFile(g_hCustomRomF8, memrom+Apple2RomSize-F8RomSize, F8RomSize, &uNumBytesRead, NULL);
|
BOOL bRes = ReadFile(g_hCustomRomF8, memrom+Apple2RomSize-F8RomSize, F8RomSize, &uNumBytesRead, NULL);
|
||||||
if (uNumBytesRead != F8RomSize)
|
if (uNumBytesRead != F8RomSize)
|
||||||
{
|
{
|
||||||
memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF
|
memcpy(memrom, OldRom, Apple2RomSize); // ROM at $D000...$FFFF
|
||||||
bRes = FALSE;
|
bRes = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1249,15 +1262,27 @@ void MemInitialize()
|
||||||
|
|
||||||
if (sg_PropertySheet.GetTheFreezesF8Rom() && IS_APPLE2)
|
if (sg_PropertySheet.GetTheFreezesF8Rom() && IS_APPLE2)
|
||||||
{
|
{
|
||||||
hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_FREEZES_F8_ROM), "ROM");
|
HGLOBAL hResData = NULL;
|
||||||
|
BYTE* pData = NULL;
|
||||||
|
|
||||||
|
HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_FREEZES_F8_ROM), "ROM");
|
||||||
|
|
||||||
if (hResInfo && (SizeofResource(NULL, hResInfo) == 0x800) && (hResData = LoadResource(NULL, hResInfo)) && (pData = (BYTE*) LockResource(hResData)))
|
if (hResInfo && (SizeofResource(NULL, hResInfo) == 0x800) && (hResData = LoadResource(NULL, hResInfo)) && (pData = (BYTE*) LockResource(hResData)))
|
||||||
{
|
{
|
||||||
memcpy(memrom+Apple2RomSize-F8RomSize, pData, F8RomSize);
|
memcpy(memrom+Apple2RomSize-F8RomSize, pData, F8RomSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
// Called by:
|
||||||
|
// . MemInitialize()
|
||||||
|
// . Snapshot_LoadState_v2()
|
||||||
|
//
|
||||||
|
// Since called by LoadState(), then this must not init any cards
|
||||||
|
// - it should only init the card I/O hooks
|
||||||
|
void MemInitializeIO(void)
|
||||||
|
{
|
||||||
|
InitIoHandlers();
|
||||||
|
|
||||||
const UINT uSlot = 0;
|
const UINT uSlot = 0;
|
||||||
RegisterIoHandler(uSlot, MemSetPaging, MemSetPaging, NULL, NULL, NULL, NULL);
|
RegisterIoHandler(uSlot, MemSetPaging, MemSetPaging, NULL, NULL, NULL, NULL);
|
||||||
|
@ -1295,11 +1320,12 @@ void MemInitialize()
|
||||||
{
|
{
|
||||||
ConfigureSoftcard(pCxRomPeripheral, 5); // $C500 : Z80 card
|
ConfigureSoftcard(pCxRomPeripheral, 5); // $C500 : Z80 card
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (g_Slot5 == CT_SAM)
|
||||||
|
ConfigureSAM(pCxRomPeripheral, 5); // $C500 : Z80 card
|
||||||
|
|
||||||
DiskLoadRom(pCxRomPeripheral, 6); // $C600 : Disk][ f/w
|
DiskLoadRom(pCxRomPeripheral, 6); // $C600 : Disk][ f/w
|
||||||
HD_Load_Rom(pCxRomPeripheral, 7); // $C700 : HDD f/w
|
HD_Load_Rom(pCxRomPeripheral, 7); // $C700 : HDD f/w
|
||||||
|
|
||||||
MemReset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline DWORD getRandomTime()
|
inline DWORD getRandomTime()
|
||||||
|
@ -1312,7 +1338,8 @@ inline DWORD getRandomTime()
|
||||||
// Called by:
|
// Called by:
|
||||||
// . MemInitialize()
|
// . MemInitialize()
|
||||||
// . ResetMachineState() eg. Power-cycle ('Apple-Go' button)
|
// . ResetMachineState() eg. Power-cycle ('Apple-Go' button)
|
||||||
// . Snapshot_LoadState()
|
// . Snapshot_LoadState_v1()
|
||||||
|
// . Snapshot_LoadState_v2()
|
||||||
void MemReset()
|
void MemReset()
|
||||||
{
|
{
|
||||||
// INITIALIZE THE PAGING TABLES
|
// INITIALIZE THE PAGING TABLES
|
||||||
|
@ -1321,9 +1348,16 @@ void MemReset()
|
||||||
|
|
||||||
// INITIALIZE THE RAM IMAGES
|
// INITIALIZE THE RAM IMAGES
|
||||||
ZeroMemory(memaux ,0x10000);
|
ZeroMemory(memaux ,0x10000);
|
||||||
|
|
||||||
ZeroMemory(memmain,0x10000);
|
ZeroMemory(memmain,0x10000);
|
||||||
|
|
||||||
|
// Init the I/O ROM vars
|
||||||
|
IO_SELECT = 0;
|
||||||
|
IO_SELECT_InternalROM = 0;
|
||||||
|
g_eExpansionRomType = eExpRomNull;
|
||||||
|
g_uPeripheralRomSlot = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
int iByte;
|
int iByte;
|
||||||
|
|
||||||
// Memory is pseudo-initialized across various models of Apple ][ //e //c
|
// Memory is pseudo-initialized across various models of Apple ][ //e //c
|
||||||
|
@ -1394,14 +1428,14 @@ void MemReset()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIP_RANDOM:
|
case MIP_RANDOM:
|
||||||
unsigned char random[ 256 + 4 ];
|
unsigned char random[ 256 ];
|
||||||
for( iByte = 0x0000; iByte < 0xC000; iByte += 256 )
|
for( iByte = 0x0000; iByte < 0xC000; iByte += 256 )
|
||||||
{
|
{
|
||||||
for( int i = 0; i < 256; i++ )
|
for( int i = 0; i < 256; i++ )
|
||||||
{
|
{
|
||||||
clock = getRandomTime();
|
clock = getRandomTime();
|
||||||
random[ i+0 ] ^= (clock >> 0) & 0xFF;
|
random[ (i+0) & 0xFF ] ^= (clock >> 0) & 0xFF;
|
||||||
random[ i+1 ] ^= (clock >> 11) & 0xFF;
|
random[ (i+1) & 0xFF ] ^= (clock >> 11) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy( &memmain[ iByte ], random, 256 );
|
memcpy( &memmain[ iByte ], random, 256 );
|
||||||
|
@ -1455,23 +1489,7 @@ void MemReset()
|
||||||
CpuInitialize();
|
CpuInitialize();
|
||||||
//Sets Caps Lock = false (Pravets 8A/C only)
|
//Sets Caps Lock = false (Pravets 8A/C only)
|
||||||
|
|
||||||
z80_reset();
|
z80_reset(); // NB. Also called above in CpuInitialize()
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
// Call by:
|
|
||||||
// . Soft-reset (Ctrl+Reset)
|
|
||||||
// . Snapshot_LoadState()
|
|
||||||
void MemResetPaging()
|
|
||||||
{
|
|
||||||
ResetPaging(0); // Initialize=0
|
|
||||||
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
|
||||||
{
|
|
||||||
P8CAPS_ON = false;
|
|
||||||
TapeWrite (0, 0, 0, 0 ,0);
|
|
||||||
FrameRefreshStatus(DRAW_LEDS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -1592,7 +1610,8 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
||||||
case 0x73: // Ramworks III set aux page number
|
case 0x73: // Ramworks III set aux page number
|
||||||
if ((value < g_uMaxExPages) && RWpages[value])
|
if ((value < g_uMaxExPages) && RWpages[value])
|
||||||
{
|
{
|
||||||
memaux = RWpages[value];
|
g_uActiveBank = value;
|
||||||
|
memaux = RWpages[g_uActiveBank];
|
||||||
UpdatePaging(0); // Initialize=0
|
UpdatePaging(0); // Initialize=0
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1670,34 +1689,218 @@ LPVOID MemGetSlotParameters(UINT uSlot)
|
||||||
// . If we were to save the state when 'modechanging' is set, then on restoring the state, the 6502 code will immediately update the read memory mode.
|
// . If we were to save the state when 'modechanging' is set, then on restoring the state, the 6502 code will immediately update the read memory mode.
|
||||||
// . This will work correctly.
|
// . This will work correctly.
|
||||||
|
|
||||||
DWORD MemGetSnapshot(SS_BaseMemory* pSS)
|
void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* const pMemMain, const BYTE* const pMemAux)
|
||||||
{
|
{
|
||||||
pSS->dwMemMode = memmode;
|
SetMemMode(MemMode);
|
||||||
pSS->bLastWriteRam = lastwriteram;
|
lastwriteram = LastWriteRam;
|
||||||
|
|
||||||
for(DWORD dwOffset = 0x0000; dwOffset < 0x10000; dwOffset+=0x100)
|
memcpy(memmain, pMemMain, nMemMainSize);
|
||||||
{
|
memcpy(memaux, pMemAux, nMemAuxSize);
|
||||||
memcpy(pSS->nMemMain+dwOffset, MemGetMainPtr((WORD)dwOffset), 0x100);
|
|
||||||
memcpy(pSS->nMemAux+dwOffset, MemGetAuxPtr((WORD)dwOffset), 0x100);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD MemSetSnapshot(SS_BaseMemory* pSS)
|
|
||||||
{
|
|
||||||
SetMemMode(pSS->dwMemMode);
|
|
||||||
lastwriteram = pSS->bLastWriteRam;
|
|
||||||
|
|
||||||
memcpy(memmain, pSS->nMemMain, nMemMainSize);
|
|
||||||
memcpy(memaux, pSS->nMemAux, nMemAuxSize);
|
|
||||||
memset(memdirty, 0, 0x100);
|
memset(memdirty, 0, 0x100);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
modechanging = 0;
|
modechanging = 0;
|
||||||
|
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v1()
|
||||||
UpdatePaging(1); // Initialize=1
|
UpdatePaging(1); // Initialize=1
|
||||||
|
}
|
||||||
return 0;
|
|
||||||
|
//
|
||||||
|
|
||||||
|
#define UNIT_AUXSLOT_VER 1
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_MEMORYMODE "Memory Mode"
|
||||||
|
#define SS_YAML_KEY_LASTRAMWRITE "Last RAM Write"
|
||||||
|
#define SS_YAML_KEY_IOSELECT "IO_SELECT"
|
||||||
|
#define SS_YAML_KEY_IOSELECT_INT "IO_SELECT_InternalROM"
|
||||||
|
#define SS_YAML_KEY_EXPANSIONROMTYPE "Expansion ROM Type"
|
||||||
|
#define SS_YAML_KEY_PERIPHERALROMSLOT "Peripheral ROM Slot"
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_CARD_80COL "80 Column"
|
||||||
|
#define SS_YAML_VALUE_CARD_EXTENDED80COL "Extended 80 Column"
|
||||||
|
#define SS_YAML_VALUE_CARD_RAMWORKSIII "RamWorksIII"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_NUMAUXBANKS "Num Aux Banks"
|
||||||
|
#define SS_YAML_KEY_ACTIVEAUXBANK "Active Aux Bank"
|
||||||
|
|
||||||
|
static std::string MemGetSnapshotStructName(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Memory");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MemGetSnapshotUnitAuxSlotName(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Auxiliary Slot");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string MemGetSnapshotMainMemStructName(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Main Memory");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string MemGetSnapshotAuxMemStructName(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Auxiliary Memory Bank");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MemSaveSnapshotMemory(YamlSaveHelper& yamlSaveHelper, bool bIsMainMem, UINT bank=0)
|
||||||
|
{
|
||||||
|
LPBYTE pMemBase = MemGetBankPtr(bank);
|
||||||
|
|
||||||
|
if (bIsMainMem)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", MemGetSnapshotMainMemStructName().c_str());
|
||||||
|
yamlSaveHelper.SaveMemory(pMemBase, 64*1024);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s%02X:\n", MemGetSnapshotAuxMemStructName().c_str(), bank-1);
|
||||||
|
yamlSaveHelper.SaveMemory(pMemBase, 64*1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
// Scope so that "Memory" & "Main Memory" are at same indent level
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", MemGetSnapshotStructName().c_str());
|
||||||
|
yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_MEMORYMODE, memmode);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_LASTRAMWRITE, lastwriteram ? 1 : 0);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IOSELECT, IO_SELECT);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IOSELECT_INT, IO_SELECT_InternalROM);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_EXPANSIONROMTYPE, (UINT) g_eExpansionRomType);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_PERIPHERALROMSLOT, g_uPeripheralRomSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
MemSaveSnapshotMemory(yamlSaveHelper, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(MemGetSnapshotStructName()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SetMemMode( yamlLoadHelper.LoadUint(SS_YAML_KEY_MEMORYMODE) );
|
||||||
|
lastwriteram = yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTRAMWRITE) ? TRUE : FALSE;
|
||||||
|
IO_SELECT = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_IOSELECT);
|
||||||
|
IO_SELECT_InternalROM = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_IOSELECT_INT);
|
||||||
|
g_eExpansionRomType = (eExpansionRomType) yamlLoadHelper.LoadUint(SS_YAML_KEY_EXPANSIONROMTYPE);
|
||||||
|
g_uPeripheralRomSlot = yamlLoadHelper.LoadUint(SS_YAML_KEY_PERIPHERALROMSLOT);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
if (!yamlLoadHelper.GetSubMap( MemGetSnapshotMainMemStructName() ))
|
||||||
|
throw std::string("Card: Expected key: ") + MemGetSnapshotMainMemStructName();
|
||||||
|
|
||||||
|
yamlLoadHelper.LoadMemory(memmain, _6502_MEM_END+1);
|
||||||
|
memset(memdirty, 0, 0x100);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
modechanging = 0;
|
||||||
|
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2()
|
||||||
|
UpdatePaging(1); // Initialize=1 (Still needed, even with call to MemUpdatePaging() - why?)
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemSaveSnapshotAux(YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
if (IS_APPLE2)
|
||||||
|
{
|
||||||
|
return; // No Aux slot for AppleII
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_APPLE2C)
|
||||||
|
{
|
||||||
|
_ASSERT(g_uMaxExPages == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
yamlSaveHelper.UnitHdr(MemGetSnapshotUnitAuxSlotName(), UNIT_AUXSLOT_VER);
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
|
std::string card = g_uMaxExPages == 0 ? SS_YAML_VALUE_CARD_80COL : // todo: support empty slot
|
||||||
|
g_uMaxExPages == 1 ? SS_YAML_VALUE_CARD_EXTENDED80COL :
|
||||||
|
SS_YAML_VALUE_CARD_RAMWORKSIII;
|
||||||
|
yamlSaveHelper.SaveString(SS_YAML_KEY_CARD, card.c_str());
|
||||||
|
yamlSaveHelper.Save("%s: %02X # [0,1..7F] 0=no aux mem, 1=128K system, etc\n", SS_YAML_KEY_NUMAUXBANKS, g_uMaxExPages);
|
||||||
|
yamlSaveHelper.Save("%s: %02X # [ 0..7E] 0=memaux\n", SS_YAML_KEY_ACTIVEAUXBANK, g_uActiveBank);
|
||||||
|
|
||||||
|
for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++)
|
||||||
|
{
|
||||||
|
MemSaveSnapshotMemory(yamlSaveHelper, false, uBank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemLoadSnapshotAux(YamlLoadHelper& yamlLoadHelper, UINT version)
|
||||||
|
{
|
||||||
|
if (version != UNIT_AUXSLOT_VER)
|
||||||
|
throw std::string(SS_YAML_KEY_UNIT ": AuxSlot: Version mismatch");
|
||||||
|
|
||||||
|
// "State"
|
||||||
|
UINT numAuxBanks = yamlLoadHelper.LoadUint(SS_YAML_KEY_NUMAUXBANKS);
|
||||||
|
UINT activeAuxBank = yamlLoadHelper.LoadUint(SS_YAML_KEY_ACTIVEAUXBANK);
|
||||||
|
|
||||||
|
std::string card = yamlLoadHelper.LoadString(SS_YAML_KEY_CARD);
|
||||||
|
if (card == SS_YAML_VALUE_CARD_80COL)
|
||||||
|
{
|
||||||
|
if (numAuxBanks != 0 || activeAuxBank != 0)
|
||||||
|
throw std::string(SS_YAML_KEY_UNIT ": AuxSlot: Bad aux slot card state");
|
||||||
|
}
|
||||||
|
else if (card == SS_YAML_VALUE_CARD_EXTENDED80COL)
|
||||||
|
{
|
||||||
|
if (numAuxBanks != 1 || activeAuxBank != 0)
|
||||||
|
throw std::string(SS_YAML_KEY_UNIT ": AuxSlot: Bad aux slot card state");
|
||||||
|
}
|
||||||
|
else if (card == SS_YAML_VALUE_CARD_RAMWORKSIII)
|
||||||
|
{
|
||||||
|
if (numAuxBanks < 2 || numAuxBanks > 0x7F || (activeAuxBank+1) > numAuxBanks)
|
||||||
|
throw std::string(SS_YAML_KEY_UNIT ": AuxSlot: Bad aux slot card state");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// todo: support empty slot
|
||||||
|
throw std::string(SS_YAML_KEY_UNIT ": AuxSlot: Unknown card: " + card);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_uMaxExPages = numAuxBanks;
|
||||||
|
g_uActiveBank = activeAuxBank;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++)
|
||||||
|
{
|
||||||
|
LPBYTE pBank = MemGetBankPtr(uBank);
|
||||||
|
if (!pBank)
|
||||||
|
{
|
||||||
|
pBank = RWpages[uBank-1] = (LPBYTE) VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
|
||||||
|
if (!pBank)
|
||||||
|
throw std::string("Card: mem alloc failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Auxiliary Memory Bankxx"
|
||||||
|
char szBank[3];
|
||||||
|
sprintf(szBank, "%02X", uBank-1);
|
||||||
|
std::string auxMemName = MemGetSnapshotAuxMemStructName() + szBank;
|
||||||
|
|
||||||
|
if (!yamlLoadHelper.GetSubMap(auxMemName))
|
||||||
|
throw std::string("Memory: Missing map name: " + auxMemName);
|
||||||
|
|
||||||
|
yamlLoadHelper.LoadMemory(pBank, _6502_MEM_END+1);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
memaux = RWpages[g_uActiveBank];
|
||||||
|
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2()
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ extern LPBYTE mem;
|
||||||
extern LPBYTE memdirty;
|
extern LPBYTE memdirty;
|
||||||
|
|
||||||
#ifdef RAMWORKS
|
#ifdef RAMWORKS
|
||||||
|
const UINT kMaxExMemoryBanks = 127; // 127 * aux mem(64K) + main mem(64K) = 8MB
|
||||||
extern UINT g_uMaxExPages; // user requested ram pages (from cmd line)
|
extern UINT g_uMaxExPages; // user requested ram pages (from cmd line)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -44,14 +45,21 @@ LPBYTE MemGetMainPtr(const WORD);
|
||||||
LPBYTE MemGetBankPtr(const UINT nBank);
|
LPBYTE MemGetBankPtr(const UINT nBank);
|
||||||
LPBYTE MemGetCxRomPeripheral();
|
LPBYTE MemGetCxRomPeripheral();
|
||||||
void MemInitialize ();
|
void MemInitialize ();
|
||||||
|
void MemInitializeROM(void);
|
||||||
|
void MemInitializeCustomF8ROM(void);
|
||||||
|
void MemInitializeIO(void);
|
||||||
BYTE MemReadFloatingBus(const ULONG uExecutedCycles);
|
BYTE MemReadFloatingBus(const ULONG uExecutedCycles);
|
||||||
BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles);
|
BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles);
|
||||||
void MemReset ();
|
void MemReset ();
|
||||||
void MemResetPaging ();
|
void MemResetPaging ();
|
||||||
void MemUpdatePaging(BOOL initialize);
|
void MemUpdatePaging(BOOL initialize);
|
||||||
LPVOID MemGetSlotParameters (UINT uSlot);
|
LPVOID MemGetSlotParameters (UINT uSlot);
|
||||||
DWORD MemGetSnapshot(SS_BaseMemory* pSS);
|
void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* const pMemMain, const BYTE* const pMemAux);
|
||||||
DWORD MemSetSnapshot(SS_BaseMemory* pSS);
|
std::string MemGetSnapshotUnitAuxSlotName(void);
|
||||||
|
void MemSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
|
||||||
|
void MemSaveSnapshotAux(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
bool MemLoadSnapshotAux(class YamlLoadHelper& yamlLoadHelper, UINT version);
|
||||||
|
|
||||||
BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
|
BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
|
||||||
|
|
||||||
|
|
|
@ -77,12 +77,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "SaveState_Structs_v1.h"
|
||||||
|
|
||||||
#include "AppleWin.h"
|
#include "AppleWin.h"
|
||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Mockingboard.h"
|
#include "Mockingboard.h"
|
||||||
#include "SoundCore.h"
|
#include "SoundCore.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#include "AY8910.h"
|
#include "AY8910.h"
|
||||||
#include "SSI263Phonemes.h"
|
#include "SSI263Phonemes.h"
|
||||||
|
@ -114,14 +117,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#define Phasor_SY6522A_Offset (1<<Phasor_SY6522A_CS)
|
#define Phasor_SY6522A_Offset (1<<Phasor_SY6522A_CS)
|
||||||
#define Phasor_SY6522B_Offset (1<<Phasor_SY6522B_CS)
|
#define Phasor_SY6522B_Offset (1<<Phasor_SY6522B_CS)
|
||||||
|
|
||||||
typedef struct
|
struct SY6522_AY8910
|
||||||
{
|
{
|
||||||
SY6522 sy6522;
|
SY6522 sy6522;
|
||||||
BYTE nAY8910Number;
|
BYTE nAY8910Number;
|
||||||
BYTE nAYCurrentRegister;
|
BYTE nAYCurrentRegister;
|
||||||
BYTE nTimerStatus;
|
BYTE nTimerStatus;
|
||||||
SSI263A SpeechChip;
|
SSI263A SpeechChip;
|
||||||
} SY6522_AY8910;
|
};
|
||||||
|
|
||||||
|
|
||||||
// IFR & IER:
|
// IFR & IER:
|
||||||
|
@ -155,8 +158,8 @@ static UINT64 g_uLastCumulativeCycles = 0;
|
||||||
|
|
||||||
// SSI263 vars:
|
// SSI263 vars:
|
||||||
static USHORT g_nSSI263Device = 0; // SSI263 device# which is generating phoneme-complete IRQ
|
static USHORT g_nSSI263Device = 0; // SSI263 device# which is generating phoneme-complete IRQ
|
||||||
static int g_nCurrentActivePhoneme = -1;
|
static volatile int g_nCurrentActivePhoneme = -1; // Modified by threads: main & SSI263Thread
|
||||||
static bool g_bStopPhoneme = false;
|
static volatile bool g_bStopPhoneme = false; // Modified by threads: main & SSI263Thread
|
||||||
static bool g_bVotraxPhoneme = false;
|
static bool g_bVotraxPhoneme = false;
|
||||||
|
|
||||||
static const DWORD SAMPLE_RATE = 44100; // Use a base freq so that DirectX (or sound h/w) doesn't have to up/down-sample
|
static const DWORD SAMPLE_RATE = 44100; // Use a base freq so that DirectX (or sound h/w) doesn't have to up/down-sample
|
||||||
|
@ -176,6 +179,7 @@ static bool g_bMBAvailable = false;
|
||||||
static SS_CARDTYPE g_SoundcardType = CT_Empty; // Use CT_Empty to mean: no soundcard
|
static SS_CARDTYPE g_SoundcardType = CT_Empty; // Use CT_Empty to mean: no soundcard
|
||||||
static bool g_bPhasorEnable = false;
|
static bool g_bPhasorEnable = false;
|
||||||
static BYTE g_nPhasorMode = 0; // 0=Mockingboard emulation, 1=Phasor native
|
static BYTE g_nPhasorMode = 0; // 0=Mockingboard emulation, 1=Phasor native
|
||||||
|
static UINT g_PhasorClockScaleFactor = 1; // for save-state only
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
|
@ -536,7 +540,7 @@ void SSI263_Play(unsigned int nPhoneme);
|
||||||
#if 0
|
#if 0
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
BYTE DurationPhonome;
|
BYTE DurationPhoneme;
|
||||||
BYTE Inflection; // I10..I3
|
BYTE Inflection; // I10..I3
|
||||||
BYTE RateInflection;
|
BYTE RateInflection;
|
||||||
BYTE CtrlArtAmp;
|
BYTE CtrlArtAmp;
|
||||||
|
@ -600,7 +604,7 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||||
}
|
}
|
||||||
pMB->SpeechChip.CurrentMode &= ~1; // Clear SSI263's D7 pin
|
pMB->SpeechChip.CurrentMode &= ~1; // Clear SSI263's D7 pin
|
||||||
|
|
||||||
pMB->SpeechChip.DurationPhonome = nValue;
|
pMB->SpeechChip.DurationPhoneme = nValue;
|
||||||
|
|
||||||
g_nSSI263Device = nDevice;
|
g_nSSI263Device = nDevice;
|
||||||
|
|
||||||
|
@ -632,7 +636,7 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||||
if(g_fh) fprintf(g_fh, "CTRL = %d, ART = 0x%02X, AMP=0x%02X\n", nValue>>7, (nValue&ARTICULATION_MASK)>>4, nValue&LITUDE_MASK);
|
if(g_fh) fprintf(g_fh, "CTRL = %d, ART = 0x%02X, AMP=0x%02X\n", nValue>>7, (nValue&ARTICULATION_MASK)>>4, nValue&LITUDE_MASK);
|
||||||
#endif
|
#endif
|
||||||
if((pMB->SpeechChip.CtrlArtAmp & CONTROL_MASK) && !(nValue & CONTROL_MASK)) // H->L
|
if((pMB->SpeechChip.CtrlArtAmp & CONTROL_MASK) && !(nValue & CONTROL_MASK)) // H->L
|
||||||
pMB->SpeechChip.CurrentMode = pMB->SpeechChip.DurationPhonome & DURATION_MODE_MASK;
|
pMB->SpeechChip.CurrentMode = pMB->SpeechChip.DurationPhoneme & DURATION_MODE_MASK;
|
||||||
pMB->SpeechChip.CtrlArtAmp = nValue;
|
pMB->SpeechChip.CtrlArtAmp = nValue;
|
||||||
break;
|
break;
|
||||||
case SSI_FILFREQ:
|
case SSI_FILFREQ:
|
||||||
|
@ -826,7 +830,7 @@ static void MB_Update()
|
||||||
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
||||||
sprintf(szDbg, "%010.3f: [MBUpdt] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X xxx\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
sprintf(szDbg, "%010.3f: [MBUpdt] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X xxx\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
||||||
OutputDebugString(szDbg);
|
OutputDebugString(szDbg);
|
||||||
if (g_fh) fprintf(g_fh, szDbg);
|
if (g_fh) fprintf(g_fh, "%s", szDbg);
|
||||||
|
|
||||||
dwByteOffset = dwCurrentWriteCursor;
|
dwByteOffset = dwCurrentWriteCursor;
|
||||||
}
|
}
|
||||||
|
@ -839,7 +843,7 @@ static void MB_Update()
|
||||||
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
||||||
sprintf(szDbg, "%010.3f: [MBUpdt] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X XXX\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
sprintf(szDbg, "%010.3f: [MBUpdt] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X XXX\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
||||||
OutputDebugString(szDbg);
|
OutputDebugString(szDbg);
|
||||||
if (g_fh) fprintf(g_fh, szDbg);
|
if (g_fh) fprintf(g_fh, "%s", szDbg);
|
||||||
|
|
||||||
dwByteOffset = dwCurrentWriteCursor;
|
dwByteOffset = dwCurrentWriteCursor;
|
||||||
}
|
}
|
||||||
|
@ -1002,11 +1006,22 @@ static void SSI263_Play(unsigned int nPhoneme)
|
||||||
#if 1
|
#if 1
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if(g_nCurrentActivePhoneme >= 0)
|
{
|
||||||
|
int nCurrPhoneme = g_nCurrentActivePhoneme; // local copy in case SSI263Thread sets it to -1
|
||||||
|
if (nCurrPhoneme >= 0)
|
||||||
{
|
{
|
||||||
// A write to DURPHON before previous phoneme has completed
|
// A write to DURPHON before previous phoneme has completed
|
||||||
g_bStopPhoneme = true;
|
g_bStopPhoneme = true;
|
||||||
hr = SSI263Voice[g_nCurrentActivePhoneme].lpDSBvoice->Stop();
|
hr = SSI263Voice[nCurrPhoneme].lpDSBvoice->Stop();
|
||||||
|
|
||||||
|
// Busy-wait until ACK from SSI263Thread
|
||||||
|
// . required to avoid data-race
|
||||||
|
while ( g_bStopPhoneme && // wait for SSI263Thread to ACK the lpDSBVoice->Stop()
|
||||||
|
g_nCurrentActivePhoneme >= 0) // wait for SSI263Thread to get end of sample event
|
||||||
|
;
|
||||||
|
|
||||||
|
g_bStopPhoneme = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_nCurrentActivePhoneme = nPhoneme;
|
g_nCurrentActivePhoneme = nPhoneme;
|
||||||
|
@ -1371,7 +1386,8 @@ void MB_Initialize()
|
||||||
// NB. Called when /g_fCurrentCLK6502/ changes
|
// NB. Called when /g_fCurrentCLK6502/ changes
|
||||||
void MB_Reinitialize()
|
void MB_Reinitialize()
|
||||||
{
|
{
|
||||||
AY8910_InitClock((int)g_fCurrentCLK6502);
|
AY8910_InitClock((int)g_fCurrentCLK6502); // todo: account for g_PhasorClockScaleFactor?
|
||||||
|
// NB. Other calls to AY8910_InitClock() use the constant CLK_6502
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1403,9 +1419,10 @@ static void ResetState()
|
||||||
|
|
||||||
//g_bMBAvailable = false;
|
//g_bMBAvailable = false;
|
||||||
|
|
||||||
//g_SoundcardType = CT_Empty;
|
// g_SoundcardType = CT_Empty; // Don't uncomment, else _ASSERT will fire in MB_Read() after an F2->MB_Reset()
|
||||||
//g_bPhasorEnable = false;
|
// g_bPhasorEnable = false;
|
||||||
g_nPhasorMode = 0;
|
g_nPhasorMode = 0;
|
||||||
|
g_PhasorClockScaleFactor = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MB_Reset()
|
void MB_Reset()
|
||||||
|
@ -1553,9 +1570,9 @@ static BYTE __stdcall PhasorIO(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, UL
|
||||||
if(g_nPhasorMode < 2)
|
if(g_nPhasorMode < 2)
|
||||||
g_nPhasorMode = nAddr & 1;
|
g_nPhasorMode = nAddr & 1;
|
||||||
|
|
||||||
double fCLK = (nAddr & 4) ? CLK_6502*2 : CLK_6502;
|
g_PhasorClockScaleFactor = (nAddr & 4) ? 2 : 1;
|
||||||
|
|
||||||
AY8910_InitClock((int)fCLK);
|
AY8910_InitClock((int)(CLK_6502 * g_PhasorClockScaleFactor));
|
||||||
|
|
||||||
return MemReadFloatingBus(nCyclesLeft);
|
return MemReadFloatingBus(nCyclesLeft);
|
||||||
}
|
}
|
||||||
|
@ -1761,45 +1778,48 @@ void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD MB_GetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot)
|
// Called by debugger - Debugger_Display.cpp
|
||||||
|
void MB_GetSnapshot_v1(SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD dwSlot)
|
||||||
{
|
{
|
||||||
pSS->Hdr.UnitHdr.dwLength = sizeof(SS_CARD_DISK2);
|
pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD_v1);
|
||||||
pSS->Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card;
|
||||||
|
pSS->Hdr.UnitHdr.hdr.v2.Version = 1;
|
||||||
|
|
||||||
pSS->Hdr.dwSlot = dwSlot;
|
pSS->Hdr.Slot = dwSlot;
|
||||||
pSS->Hdr.dwType = CT_MockingboardC;
|
pSS->Hdr.Type = CT_MockingboardC;
|
||||||
|
|
||||||
UINT nMbCardNum = dwSlot - SLOT4;
|
UINT nMbCardNum = dwSlot - SLOT4;
|
||||||
UINT nDeviceNum = nMbCardNum*2;
|
UINT nDeviceNum = nMbCardNum*2;
|
||||||
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
||||||
|
|
||||||
for(UINT i=0; i<MB_UNITS_PER_CARD; i++)
|
for(UINT i=0; i<MB_UNITS_PER_CARD_v1; i++)
|
||||||
{
|
{
|
||||||
memcpy(&pSS->Unit[i].RegsSY6522, &pMB->sy6522, sizeof(SY6522));
|
memcpy(&pSS->Unit[i].RegsSY6522, &pMB->sy6522, sizeof(SY6522));
|
||||||
memcpy(&pSS->Unit[i].RegsAY8910, AY8910_GetRegsPtr(nDeviceNum), 16);
|
memcpy(&pSS->Unit[i].RegsAY8910, AY8910_GetRegsPtr(nDeviceNum), 16);
|
||||||
memcpy(&pSS->Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A));
|
memcpy(&pSS->Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A));
|
||||||
pSS->Unit[i].nAYCurrentRegister = pMB->nAYCurrentRegister;
|
pSS->Unit[i].nAYCurrentRegister = pMB->nAYCurrentRegister;
|
||||||
|
pSS->Unit[i].bTimer1IrqPending = false;
|
||||||
|
pSS->Unit[i].bTimer2IrqPending = false;
|
||||||
|
pSS->Unit[i].bSpeechIrqPending = false;
|
||||||
|
|
||||||
nDeviceNum++;
|
nDeviceNum++;
|
||||||
pMB++;
|
pMB++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD /*dwSlot*/)
|
int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD /*dwSlot*/)
|
||||||
{
|
{
|
||||||
if(pSS->Hdr.UnitHdr.dwVersion != MAKE_VERSION(1,0,0,0))
|
if(pSS->Hdr.UnitHdr.hdr.v1.dwVersion != MAKE_VERSION(1,0,0,0))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
UINT nMbCardNum = pSS->Hdr.dwSlot - SLOT4;
|
UINT nMbCardNum = pSS->Hdr.Slot - SLOT4;
|
||||||
UINT nDeviceNum = nMbCardNum*2;
|
UINT nDeviceNum = nMbCardNum*2;
|
||||||
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
||||||
|
|
||||||
g_nSSI263Device = 0;
|
g_nSSI263Device = 0;
|
||||||
g_nCurrentActivePhoneme = -1;
|
g_nCurrentActivePhoneme = -1;
|
||||||
|
|
||||||
for(UINT i=0; i<MB_UNITS_PER_CARD; i++)
|
for(UINT i=0; i<MB_UNITS_PER_CARD_v1; i++)
|
||||||
{
|
{
|
||||||
memcpy(&pMB->sy6522, &pSS->Unit[i].RegsSY6522, sizeof(SY6522));
|
memcpy(&pMB->sy6522, &pSS->Unit[i].RegsSY6522, sizeof(SY6522));
|
||||||
memcpy(AY8910_GetRegsPtr(nDeviceNum), &pSS->Unit[i].RegsAY8910, 16);
|
memcpy(AY8910_GetRegsPtr(nDeviceNum), &pSS->Unit[i].RegsAY8910, 16);
|
||||||
|
@ -1814,7 +1834,7 @@ DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD /*dwSlot*/)
|
||||||
// FIX THIS:
|
// FIX THIS:
|
||||||
// . Speech chip could be Votrax instead
|
// . Speech chip could be Votrax instead
|
||||||
// . Is this IRQ compatible with Phasor?
|
// . Is this IRQ compatible with Phasor?
|
||||||
if(pMB->SpeechChip.DurationPhonome)
|
if(pMB->SpeechChip.DurationPhoneme)
|
||||||
{
|
{
|
||||||
g_nSSI263Device = nDeviceNum;
|
g_nSSI263Device = nDeviceNum;
|
||||||
|
|
||||||
|
@ -1832,3 +1852,357 @@ DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD /*dwSlot*/)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
static UINT DoWriteFile(const HANDLE hFile, const void* const pData, const UINT Length)
|
||||||
|
{
|
||||||
|
DWORD dwBytesWritten;
|
||||||
|
BOOL bRes = WriteFile( hFile,
|
||||||
|
pData,
|
||||||
|
Length,
|
||||||
|
&dwBytesWritten,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if(!bRes || (dwBytesWritten != Length))
|
||||||
|
{
|
||||||
|
//dwError = GetLastError();
|
||||||
|
throw std::string("Card: save error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return dwBytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT DoReadFile(const HANDLE hFile, void* const pData, const UINT Length)
|
||||||
|
{
|
||||||
|
DWORD dwBytesRead;
|
||||||
|
BOOL bRes = ReadFile( hFile,
|
||||||
|
pData,
|
||||||
|
Length,
|
||||||
|
&dwBytesRead,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (dwBytesRead != Length)
|
||||||
|
throw std::string("Card: file corrupt");
|
||||||
|
|
||||||
|
return dwBytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
const UINT NUM_MB_UNITS = 2;
|
||||||
|
const UINT NUM_PHASOR_UNITS = 2;
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_MB_UNIT "Unit"
|
||||||
|
#define SS_YAML_KEY_SY6522 "SY6522"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_ORB "ORB"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_ORA "ORA"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_DDRB "DDRB"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_DDRA "DDRA"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_T1_COUNTER "Timer1 Counter"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_T1_LATCH "Timer1 Latch"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_T2_COUNTER "Timer2 Counter"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_T2_LATCH "Timer2 Latch"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT "Serial Shift"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_ACR "ACR"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_PCR "PCR"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_IFR "IFR"
|
||||||
|
#define SS_YAML_KEY_SY6522_REG_IER "IER"
|
||||||
|
#define SS_YAML_KEY_SSI263 "SSI263"
|
||||||
|
#define SS_YAML_KEY_SSI263_REG_DUR_PHON "Duration / Phoneme"
|
||||||
|
#define SS_YAML_KEY_SSI263_REG_INF "Inflection"
|
||||||
|
#define SS_YAML_KEY_SSI263_REG_RATE_INF "Rate / Inflection"
|
||||||
|
#define SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP "Control / Articulation / Amplitude"
|
||||||
|
#define SS_YAML_KEY_SSI263_REG_FILTER_FREQ "Filter Frequency"
|
||||||
|
#define SS_YAML_KEY_SSI263_REG_CURRENT_MODE "Current Mode"
|
||||||
|
#define SS_YAML_KEY_AY_CURR_REG "AY Current Register"
|
||||||
|
#define SS_YAML_KEY_TIMER1_IRQ "Timer1 IRQ Pending"
|
||||||
|
#define SS_YAML_KEY_TIMER2_IRQ "Timer2 IRQ Pending"
|
||||||
|
#define SS_YAML_KEY_SPEECH_IRQ "Speech IRQ Pending"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_PHASOR_UNIT "Unit"
|
||||||
|
#define SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR "Clock Scale Factor"
|
||||||
|
#define SS_YAML_KEY_PHASOR_MODE "Mode"
|
||||||
|
|
||||||
|
std::string MB_GetSnapshotCardName(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Mockingboard C");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Phasor_GetSnapshotCardName(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Phasor");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SaveSnapshotSY6522(YamlSaveHelper& yamlSaveHelper, SY6522& sy6522)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", SS_YAML_KEY_SY6522);
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_ORB, sy6522.ORB);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_ORA, sy6522.ORA);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_DDRB, sy6522.DDRB);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_DDRA, sy6522.DDRA);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_SY6522_REG_T1_COUNTER, sy6522.TIMER1_COUNTER.w);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_SY6522_REG_T1_LATCH, sy6522.TIMER1_LATCH.w);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_SY6522_REG_T2_COUNTER, sy6522.TIMER2_COUNTER.w);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_SY6522_REG_T2_LATCH, sy6522.TIMER2_LATCH.w);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT, sy6522.SERIAL_SHIFT);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_ACR, sy6522.ACR);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_PCR, sy6522.PCR);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_IFR, sy6522.IFR);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_IER, sy6522.IER);
|
||||||
|
// NB. No need to write ORA_NO_HS, since same data as ORA, just without handshake
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SaveSnapshotSSI263(YamlSaveHelper& yamlSaveHelper, SSI263A& ssi263)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", SS_YAML_KEY_SSI263);
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_DUR_PHON, ssi263.DurationPhoneme);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_INF, ssi263.Inflection);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_RATE_INF, ssi263.RateInflection);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP, ssi263.CtrlArtAmp);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_FILTER_FREQ, ssi263.FilterFreq);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_CURRENT_MODE, ssi263.CurrentMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
|
||||||
|
{
|
||||||
|
const UINT nMbCardNum = uSlot - SLOT4;
|
||||||
|
UINT nDeviceNum = nMbCardNum*2;
|
||||||
|
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
||||||
|
|
||||||
|
YamlSaveHelper::Slot slot(yamlSaveHelper, MB_GetSnapshotCardName(), uSlot, 1); // fixme: object should be just 1 Mockingboard card & it will know its slot
|
||||||
|
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
|
for(UINT i=0; i<NUM_MB_UNITS; i++)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label unit(yamlSaveHelper, "%s%d:\n", SS_YAML_KEY_MB_UNIT, i);
|
||||||
|
|
||||||
|
SaveSnapshotSY6522(yamlSaveHelper, pMB->sy6522);
|
||||||
|
AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum, std::string(""));
|
||||||
|
SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip);
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister);
|
||||||
|
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, "false");
|
||||||
|
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, "false");
|
||||||
|
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, "false");
|
||||||
|
|
||||||
|
nDeviceNum++;
|
||||||
|
pMB++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoadSnapshotSY6522(YamlLoadHelper& yamlLoadHelper, SY6522& sy6522)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_SY6522))
|
||||||
|
throw std::string("Card: Expected key: ") + std::string(SS_YAML_KEY_SY6522);
|
||||||
|
|
||||||
|
sy6522.ORB = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_ORB);
|
||||||
|
sy6522.ORA = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_ORA);
|
||||||
|
sy6522.DDRB = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_DDRB);
|
||||||
|
sy6522.DDRA = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_DDRA);
|
||||||
|
sy6522.TIMER1_COUNTER.w = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_T1_COUNTER);
|
||||||
|
sy6522.TIMER1_LATCH.w = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_T1_LATCH);
|
||||||
|
sy6522.TIMER2_COUNTER.w = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_T2_COUNTER);
|
||||||
|
sy6522.TIMER2_LATCH.w = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_T2_LATCH);
|
||||||
|
sy6522.SERIAL_SHIFT = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT);
|
||||||
|
sy6522.ACR = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_ACR);
|
||||||
|
sy6522.PCR = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_PCR);
|
||||||
|
sy6522.IFR = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_IFR);
|
||||||
|
sy6522.IER = yamlLoadHelper.LoadUint(SS_YAML_KEY_SY6522_REG_IER);
|
||||||
|
sy6522.ORA_NO_HS = 0; // Not saved
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoadSnapshotSSI263(YamlLoadHelper& yamlLoadHelper, SSI263A& ssi263)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_SSI263))
|
||||||
|
throw std::string("Card: Expected key: ") + std::string(SS_YAML_KEY_SSI263);
|
||||||
|
|
||||||
|
ssi263.DurationPhoneme = yamlLoadHelper.LoadUint(SS_YAML_KEY_SSI263_REG_DUR_PHON);
|
||||||
|
ssi263.Inflection = yamlLoadHelper.LoadUint(SS_YAML_KEY_SSI263_REG_INF);
|
||||||
|
ssi263.RateInflection = yamlLoadHelper.LoadUint(SS_YAML_KEY_SSI263_REG_RATE_INF);
|
||||||
|
ssi263.CtrlArtAmp = yamlLoadHelper.LoadUint(SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP);
|
||||||
|
ssi263.FilterFreq = yamlLoadHelper.LoadUint(SS_YAML_KEY_SSI263_REG_FILTER_FREQ);
|
||||||
|
ssi263.CurrentMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_SSI263_REG_CURRENT_MODE);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||||
|
{
|
||||||
|
if (slot != 4 && slot != 5) // fixme
|
||||||
|
throw std::string("Card: wrong slot");
|
||||||
|
|
||||||
|
if (version != 1)
|
||||||
|
throw std::string("Card: wrong version");
|
||||||
|
|
||||||
|
AY8910UpdateSetCycles();
|
||||||
|
|
||||||
|
const UINT nMbCardNum = slot - SLOT4;
|
||||||
|
UINT nDeviceNum = nMbCardNum*2;
|
||||||
|
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
||||||
|
|
||||||
|
g_nSSI263Device = 0;
|
||||||
|
g_nCurrentActivePhoneme = -1;
|
||||||
|
|
||||||
|
for(UINT i=0; i<NUM_MB_UNITS; i++)
|
||||||
|
{
|
||||||
|
char szNum[2] = {'0'+i,0};
|
||||||
|
std::string unit = std::string(SS_YAML_KEY_MB_UNIT) + std::string(szNum);
|
||||||
|
if (!yamlLoadHelper.GetSubMap(unit))
|
||||||
|
throw std::string("Card: Expected key: ") + std::string(unit);
|
||||||
|
|
||||||
|
LoadSnapshotSY6522(yamlLoadHelper, pMB->sy6522);
|
||||||
|
AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum, std::string(""));
|
||||||
|
LoadSnapshotSSI263(yamlLoadHelper, pMB->SpeechChip);
|
||||||
|
|
||||||
|
pMB->nAYCurrentRegister = yamlLoadHelper.LoadUint(SS_YAML_KEY_AY_CURR_REG);
|
||||||
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER1_IRQ); // Consume
|
||||||
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER2_IRQ); // Consume
|
||||||
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_SPEECH_IRQ); // Consume
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
StartTimer(pMB); // Attempt to start timer
|
||||||
|
|
||||||
|
// Crude - currently only support a single speech chip
|
||||||
|
// FIX THIS:
|
||||||
|
// . Speech chip could be Votrax instead
|
||||||
|
// . Is this IRQ compatible with Phasor?
|
||||||
|
if(pMB->SpeechChip.DurationPhoneme)
|
||||||
|
{
|
||||||
|
g_nSSI263Device = nDeviceNum;
|
||||||
|
|
||||||
|
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL))
|
||||||
|
{
|
||||||
|
pMB->sy6522.IFR |= IxR_PERIPHERAL;
|
||||||
|
UpdateIFR(pMB);
|
||||||
|
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nDeviceNum++;
|
||||||
|
pMB++;
|
||||||
|
}
|
||||||
|
|
||||||
|
AY8910_InitClock((int)CLK_6502);
|
||||||
|
|
||||||
|
// Setup in MB_InitializeIO() -> MB_SetSoundcardType()
|
||||||
|
g_SoundcardType = CT_Empty;
|
||||||
|
g_bPhasorEnable = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Phasor_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
|
||||||
|
{
|
||||||
|
if (uSlot != 4)
|
||||||
|
throw std::string("Card: Phasor only supported in slot-4");
|
||||||
|
|
||||||
|
UINT nDeviceNum = 0;
|
||||||
|
SY6522_AY8910* pMB = &g_MB[0]; // fixme: Phasor uses MB's slot4(2x6522), slot4(2xSSI263), but slot4+5(4xAY8910)
|
||||||
|
|
||||||
|
YamlSaveHelper::Slot slot(yamlSaveHelper, Phasor_GetSnapshotCardName(), uSlot, 1); // fixme: object should be just 1 Mockingboard card & it will know its slot
|
||||||
|
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR, g_PhasorClockScaleFactor);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASOR_MODE, g_nPhasorMode);
|
||||||
|
|
||||||
|
for(UINT i=0; i<NUM_PHASOR_UNITS; i++)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label unit(yamlSaveHelper, "%s%d:\n", SS_YAML_KEY_PHASOR_UNIT, i);
|
||||||
|
|
||||||
|
SaveSnapshotSY6522(yamlSaveHelper, pMB->sy6522);
|
||||||
|
AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum+0, std::string("-A"));
|
||||||
|
AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum+1, std::string("-B"));
|
||||||
|
SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip);
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister);
|
||||||
|
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, "false");
|
||||||
|
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, "false");
|
||||||
|
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, "false");
|
||||||
|
|
||||||
|
nDeviceNum += 2;
|
||||||
|
pMB++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||||
|
{
|
||||||
|
if (slot != 4) // fixme
|
||||||
|
throw std::string("Card: wrong slot");
|
||||||
|
|
||||||
|
if (version != 1)
|
||||||
|
throw std::string("Card: wrong version");
|
||||||
|
|
||||||
|
g_PhasorClockScaleFactor = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR);
|
||||||
|
g_nPhasorMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASOR_MODE);
|
||||||
|
|
||||||
|
AY8910UpdateSetCycles();
|
||||||
|
|
||||||
|
UINT nDeviceNum = 0;
|
||||||
|
SY6522_AY8910* pMB = &g_MB[0];
|
||||||
|
|
||||||
|
g_nSSI263Device = 0;
|
||||||
|
g_nCurrentActivePhoneme = -1;
|
||||||
|
|
||||||
|
for(UINT i=0; i<NUM_PHASOR_UNITS; i++)
|
||||||
|
{
|
||||||
|
char szNum[2] = {'0'+i,0};
|
||||||
|
std::string unit = std::string(SS_YAML_KEY_MB_UNIT) + std::string(szNum);
|
||||||
|
if (!yamlLoadHelper.GetSubMap(unit))
|
||||||
|
throw std::string("Card: Expected key: ") + std::string(unit);
|
||||||
|
|
||||||
|
LoadSnapshotSY6522(yamlLoadHelper, pMB->sy6522);
|
||||||
|
AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum+0, std::string("-A"));
|
||||||
|
AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum+1, std::string("-B"));
|
||||||
|
LoadSnapshotSSI263(yamlLoadHelper, pMB->SpeechChip);
|
||||||
|
|
||||||
|
pMB->nAYCurrentRegister = yamlLoadHelper.LoadUint(SS_YAML_KEY_AY_CURR_REG);
|
||||||
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER1_IRQ); // Consume
|
||||||
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER2_IRQ); // Consume
|
||||||
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_SPEECH_IRQ); // Consume
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
StartTimer(pMB); // Attempt to start timer
|
||||||
|
|
||||||
|
// Crude - currently only support a single speech chip
|
||||||
|
// FIX THIS:
|
||||||
|
// . Speech chip could be Votrax instead
|
||||||
|
// . Is this IRQ compatible with Phasor?
|
||||||
|
if(pMB->SpeechChip.DurationPhoneme)
|
||||||
|
{
|
||||||
|
g_nSSI263Device = nDeviceNum;
|
||||||
|
|
||||||
|
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL))
|
||||||
|
{
|
||||||
|
pMB->sy6522.IFR |= IxR_PERIPHERAL;
|
||||||
|
UpdateIFR(pMB);
|
||||||
|
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nDeviceNum += 2;
|
||||||
|
pMB++;
|
||||||
|
}
|
||||||
|
|
||||||
|
AY8910_InitClock((int)(CLK_6502 * g_PhasorClockScaleFactor));
|
||||||
|
|
||||||
|
// Setup in MB_InitializeIO() -> MB_SetSoundcardType()
|
||||||
|
g_SoundcardType = CT_Empty;
|
||||||
|
g_bPhasorEnable = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -22,5 +22,13 @@ double MB_GetFramePeriod();
|
||||||
bool MB_IsActive();
|
bool MB_IsActive();
|
||||||
DWORD MB_GetVolume();
|
DWORD MB_GetVolume();
|
||||||
void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax);
|
void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax);
|
||||||
DWORD MB_GetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot);
|
|
||||||
DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot);
|
void MB_GetSnapshot_v1(struct SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD dwSlot); // For debugger
|
||||||
|
int MB_SetSnapshot_v1(const struct SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD dwSlot);
|
||||||
|
std::string MB_GetSnapshotCardName(void);
|
||||||
|
void MB_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
|
||||||
|
bool MB_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||||
|
|
||||||
|
std::string Phasor_GetSnapshotCardName(void);
|
||||||
|
void Phasor_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
|
||||||
|
bool Phasor_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||||
|
|
|
@ -41,7 +41,7 @@ Etc.
|
||||||
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Structs.h"
|
#include "SaveState_Structs_common.h"
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
|
@ -50,6 +50,7 @@ Etc.
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "MouseInterface.h"
|
#include "MouseInterface.h"
|
||||||
#include "SoundCore.h" // SAFE_RELEASE()
|
#include "SoundCore.h" // SAFE_RELEASE()
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#include "..\resource\resource.h"
|
#include "..\resource\resource.h"
|
||||||
|
|
||||||
|
@ -210,7 +211,7 @@ void CMouseInterface::Reset()
|
||||||
m_iMinY = 0;
|
m_iMinY = 0;
|
||||||
m_iMaxY = 1023;
|
m_iMaxY = 1023;
|
||||||
|
|
||||||
m_bButtons[0] = m_bButtons[1] = FALSE;
|
m_bButtons[0] = m_bButtons[1] = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -447,15 +448,13 @@ void CMouseInterface::OnMouseEvent(bool bEventVBL)
|
||||||
if ( !( m_byMode & MODE_MOUSE_ON ) ) // Mouse Off
|
if ( !( m_byMode & MODE_MOUSE_ON ) ) // Mouse Off
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BOOL bBtn0 = m_bButtons[0];
|
|
||||||
BOOL bBtn1 = m_bButtons[1];
|
|
||||||
if ( m_nX != m_iX || m_nY != m_iY )
|
if ( m_nX != m_iX || m_nY != m_iY )
|
||||||
{
|
{
|
||||||
byState |= STAT_INT_MOVEMENT|STAT_MOVEMENT_SINCE_READMOUSE; // X/Y moved since last READMOUSE | Movement interrupt
|
byState |= STAT_INT_MOVEMENT|STAT_MOVEMENT_SINCE_READMOUSE; // X/Y moved since last READMOUSE | Movement interrupt
|
||||||
m_byState |= STAT_MOVEMENT_SINCE_READMOUSE; // [TC] Used by CopyII+9.1 and ProTERM3.1
|
m_byState |= STAT_MOVEMENT_SINCE_READMOUSE; // [TC] Used by CopyII+9.1 and ProTERM3.1
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_bBtn0 != bBtn0 || m_bBtn1 != bBtn1 )
|
if ( m_bBtn0 != m_bButtons[0] || m_bBtn1 != m_bButtons[1] )
|
||||||
byState |= STAT_INT_BUTTON; // Button 0/1 interrupt
|
byState |= STAT_INT_BUTTON; // Button 0/1 interrupt
|
||||||
if ( bEventVBL )
|
if ( bEventVBL )
|
||||||
byState |= STAT_INT_VBL;
|
byState |= STAT_INT_VBL;
|
||||||
|
@ -495,8 +494,8 @@ void CMouseInterface::Clear()
|
||||||
m_byState = 0;
|
m_byState = 0;
|
||||||
m_nX = 0;
|
m_nX = 0;
|
||||||
m_nY = 0;
|
m_nY = 0;
|
||||||
m_bBtn0 = 0;
|
m_bBtn0 = false;
|
||||||
m_bBtn1 = 0;
|
m_bBtn1 = false;
|
||||||
SetPositionAbs( 0, 0 );
|
SetPositionAbs( 0, 0 );
|
||||||
|
|
||||||
// CpuIrqDeassert(IS_MOUSE);
|
// CpuIrqDeassert(IS_MOUSE);
|
||||||
|
@ -594,10 +593,168 @@ void CMouseInterface::SetPositionRel(long dX, long dY, int* pOutOfBoundsX, int*
|
||||||
|
|
||||||
void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State)
|
void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State)
|
||||||
{
|
{
|
||||||
m_bButtons[Button]= (State == BUTTON_DOWN) ? TRUE : FALSE;
|
m_bButtons[Button] = (State == BUTTON_DOWN);
|
||||||
OnMouseEvent();
|
OnMouseEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_CARD_MOUSE "Mouse Card"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_MC6821 "MC6821"
|
||||||
|
#define SS_YAML_KEY_PRA "PRA"
|
||||||
|
#define SS_YAML_KEY_DDRA "DDRA"
|
||||||
|
#define SS_YAML_KEY_CRA "CRA"
|
||||||
|
#define SS_YAML_KEY_PRB "PRB"
|
||||||
|
#define SS_YAML_KEY_DDRB "DDRB"
|
||||||
|
#define SS_YAML_KEY_CRB "CRB"
|
||||||
|
#define SS_YAML_KEY_IA "IA"
|
||||||
|
#define SS_YAML_KEY_IB "IB"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_DATALEN "DataLen"
|
||||||
|
#define SS_YAML_KEY_MODE "Mode"
|
||||||
|
#define SS_YAML_KEY_6821B "6821B"
|
||||||
|
#define SS_YAML_KEY_6821A "6821A"
|
||||||
|
#define SS_YAML_KEY_BUFF "Buffer"
|
||||||
|
#define SS_YAML_KEY_BUFFPOS "Buffer Position"
|
||||||
|
#define SS_YAML_KEY_MOUSESTATE "State"
|
||||||
|
#define SS_YAML_KEY_X "X"
|
||||||
|
#define SS_YAML_KEY_Y "Y"
|
||||||
|
#define SS_YAML_KEY_BTN0 "Btn0"
|
||||||
|
#define SS_YAML_KEY_BTN1 "Btn1"
|
||||||
|
#define SS_YAML_KEY_VBL "VBL"
|
||||||
|
#define SS_YAML_KEY_IX "iX"
|
||||||
|
#define SS_YAML_KEY_IMINX "iMinX"
|
||||||
|
#define SS_YAML_KEY_IMAXX "iMaxX"
|
||||||
|
#define SS_YAML_KEY_IY "iY"
|
||||||
|
#define SS_YAML_KEY_IMINY "iMinY"
|
||||||
|
#define SS_YAML_KEY_IMAXY "iMaxY"
|
||||||
|
#define SS_YAML_KEY_BUTTON0 "Button0"
|
||||||
|
#define SS_YAML_KEY_BUTTON1 "Button1"
|
||||||
|
#define SS_YAML_KEY_ENABLED "Enabled"
|
||||||
|
|
||||||
|
std::string CMouseInterface::GetSnapshotCardName(void)
|
||||||
|
{
|
||||||
|
static const std::string name(SS_YAML_VALUE_CARD_MOUSE);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMouseInterface::SaveSnapshotMC6821(YamlSaveHelper& yamlSaveHelper, std::string key)
|
||||||
|
{
|
||||||
|
mc6821_t mc6821;
|
||||||
|
BYTE byIA;
|
||||||
|
BYTE byIB;
|
||||||
|
|
||||||
|
m_6821.Get6821(mc6821, byIA, byIB);
|
||||||
|
|
||||||
|
YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", key.c_str());
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_PRA, mc6821.pra);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_DDRA, mc6821.ddra);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_CRA, mc6821.cra);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_PRB, mc6821.prb);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_DDRB, mc6821.ddrb);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_CRB, mc6821.crb);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IA, byIA);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IB, byIB);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMouseInterface::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
if (!m_bActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
YamlSaveHelper::Slot slot(yamlSaveHelper, GetSnapshotCardName(), m_uSlot, 1);
|
||||||
|
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
SaveSnapshotMC6821(yamlSaveHelper, SS_YAML_KEY_MC6821);
|
||||||
|
yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DATALEN, m_nDataLen);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_MODE, m_byMode);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_6821B, m_by6821B);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_6821A, m_by6821A);
|
||||||
|
|
||||||
|
// New label
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label buffer(yamlSaveHelper, "%s:\n", SS_YAML_KEY_BUFF);
|
||||||
|
yamlSaveHelper.SaveMemory(m_byBuff, sizeof(m_byBuff));
|
||||||
|
}
|
||||||
|
|
||||||
|
yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BUFFPOS, m_nBuffPos);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_MOUSESTATE, m_byState);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_X, m_nX);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_Y, m_nY);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_BTN0, m_bBtn0);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_BTN1, m_bBtn1);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_VBL, m_bVBL);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IX, m_iX);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IMINX, m_iMinX);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IMAXX, m_iMaxX);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IY, m_iY);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IMINY, m_iMinY);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IMAXY, m_iMaxY);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_BUTTON0, m_bButtons[0]);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_BUTTON1, m_bButtons[1]);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_ENABLED, m_bEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMouseInterface::LoadSnapshotMC6821(YamlLoadHelper& yamlLoadHelper, std::string key)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(key))
|
||||||
|
throw std::string("Card: Expected key: ") + key;
|
||||||
|
|
||||||
|
mc6821_t mc6821;
|
||||||
|
mc6821.pra = yamlLoadHelper.LoadUint(SS_YAML_KEY_PRA);
|
||||||
|
mc6821.ddra = yamlLoadHelper.LoadUint(SS_YAML_KEY_DDRA);
|
||||||
|
mc6821.cra = yamlLoadHelper.LoadUint(SS_YAML_KEY_CRA);
|
||||||
|
mc6821.prb = yamlLoadHelper.LoadUint(SS_YAML_KEY_PRB);
|
||||||
|
mc6821.ddrb = yamlLoadHelper.LoadUint(SS_YAML_KEY_DDRB);
|
||||||
|
mc6821.crb = yamlLoadHelper.LoadUint(SS_YAML_KEY_CRB);
|
||||||
|
|
||||||
|
BYTE byIA = yamlLoadHelper.LoadUint(SS_YAML_KEY_IA);
|
||||||
|
BYTE byIB = yamlLoadHelper.LoadUint(SS_YAML_KEY_IB);
|
||||||
|
|
||||||
|
m_6821.Set6821(mc6821, byIA, byIB);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMouseInterface::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||||
|
{
|
||||||
|
if (slot != 4) // fixme
|
||||||
|
throw std::string("Card: wrong slot");
|
||||||
|
|
||||||
|
if (version != 1)
|
||||||
|
throw std::string("Card: wrong version");
|
||||||
|
|
||||||
|
LoadSnapshotMC6821(yamlLoadHelper, SS_YAML_KEY_MC6821);
|
||||||
|
|
||||||
|
m_nDataLen = yamlLoadHelper.LoadUint(SS_YAML_KEY_DATALEN);
|
||||||
|
m_byMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_MODE);
|
||||||
|
m_by6821B = yamlLoadHelper.LoadUint(SS_YAML_KEY_6821B);
|
||||||
|
m_by6821A = yamlLoadHelper.LoadUint(SS_YAML_KEY_6821A);
|
||||||
|
|
||||||
|
if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_BUFF))
|
||||||
|
throw std::string("Card: Expected key: "SS_YAML_KEY_BUFF);
|
||||||
|
yamlLoadHelper.LoadMemory(m_byBuff, sizeof(m_byBuff));
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
|
||||||
|
m_nBuffPos = yamlLoadHelper.LoadUint(SS_YAML_KEY_BUFFPOS);
|
||||||
|
m_byState = yamlLoadHelper.LoadUint(SS_YAML_KEY_MOUSESTATE);
|
||||||
|
m_nX = yamlLoadHelper.LoadInt(SS_YAML_KEY_X);
|
||||||
|
m_nY = yamlLoadHelper.LoadInt(SS_YAML_KEY_Y);
|
||||||
|
m_bBtn0 = yamlLoadHelper.LoadBool(SS_YAML_KEY_BTN0);
|
||||||
|
m_bBtn1 = yamlLoadHelper.LoadBool(SS_YAML_KEY_BTN1);
|
||||||
|
m_bVBL = yamlLoadHelper.LoadBool(SS_YAML_KEY_VBL);
|
||||||
|
m_iX = yamlLoadHelper.LoadInt(SS_YAML_KEY_IX);
|
||||||
|
m_iMinX = yamlLoadHelper.LoadInt(SS_YAML_KEY_IMINX);
|
||||||
|
m_iMaxX = yamlLoadHelper.LoadInt(SS_YAML_KEY_IMAXX);
|
||||||
|
m_iY = yamlLoadHelper.LoadInt(SS_YAML_KEY_IY);
|
||||||
|
m_iMinY = yamlLoadHelper.LoadInt(SS_YAML_KEY_IMINY);
|
||||||
|
m_iMaxY = yamlLoadHelper.LoadInt(SS_YAML_KEY_IMAXY);
|
||||||
|
m_bButtons[0] = yamlLoadHelper.LoadBool(SS_YAML_KEY_BUTTON0);
|
||||||
|
m_bButtons[1] = yamlLoadHelper.LoadBool(SS_YAML_KEY_BUTTON1);
|
||||||
|
m_bEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_ENABLED); // MemInitializeIO() calls Initialize() which sets true
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// DirectInput interface
|
// DirectInput interface
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
|
@ -12,15 +12,14 @@ public:
|
||||||
void Initialize(LPBYTE pCxRomPeripheral, UINT uSlot);
|
void Initialize(LPBYTE pCxRomPeripheral, UINT uSlot);
|
||||||
void Uninitialize();
|
void Uninitialize();
|
||||||
void Reset();
|
void Reset();
|
||||||
void SetSlotRom();
|
|
||||||
static BYTE __stdcall IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
|
static BYTE __stdcall IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
|
||||||
static BYTE __stdcall IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
|
static BYTE __stdcall IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft);
|
||||||
|
|
||||||
void SetPositionRel(long dx, long dy, int* pOutOfBoundsX, int* pOutOfBoundsY);
|
void SetPositionRel(long dx, long dy, int* pOutOfBoundsX, int* pOutOfBoundsY);
|
||||||
void SetButton(eBUTTON Button, eBUTTONSTATE State);
|
void SetButton(eBUTTON Button, eBUTTONSTATE State);
|
||||||
bool IsActive() { return m_bActive; }
|
bool IsActive() { return m_bActive; }
|
||||||
bool IsEnabled() { return m_bEnabled; }
|
bool IsEnabled() { return m_bEnabled; } // NB. m_bEnabled == true implies that m_bActive == true
|
||||||
bool IsActiveAndEnabled() { return IsActive() && IsEnabled(); }
|
bool IsActiveAndEnabled() { return IsActive() && IsEnabled(); } // todo: just use IsEnabled()
|
||||||
void SetEnabled(bool bEnabled) { m_bEnabled = bEnabled; }
|
void SetEnabled(bool bEnabled) { m_bEnabled = bEnabled; }
|
||||||
void SetVBlank(bool bVBL);
|
void SetVBlank(bool bVBL);
|
||||||
void GetXY(int& iX, int& iMinX, int& iMaxX, int& iY, int& iMinY, int& iMaxY)
|
void GetXY(int& iX, int& iMinX, int& iMaxX, int& iY, int& iMinY, int& iMaxY)
|
||||||
|
@ -38,7 +37,12 @@ public:
|
||||||
m_iY = iY;
|
m_iY = iY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GetSnapshotCardName(void);
|
||||||
|
void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void SetSlotRom();
|
||||||
void On6821_A(BYTE byData);
|
void On6821_A(BYTE byData);
|
||||||
void On6821_B(BYTE byData);
|
void On6821_B(BYTE byData);
|
||||||
void OnCommand();
|
void OnCommand();
|
||||||
|
@ -55,6 +59,8 @@ protected:
|
||||||
void SetClampX(int iMinX, int iMaxX);
|
void SetClampX(int iMinX, int iMaxX);
|
||||||
void SetClampY(int iMinY, int iMaxY);
|
void SetClampY(int iMinY, int iMaxY);
|
||||||
|
|
||||||
|
void SaveSnapshotMC6821(class YamlSaveHelper& yamlSaveHelper, std::string key);
|
||||||
|
void LoadSnapshotMC6821(class YamlLoadHelper& yamlLoadHelper, std::string key);
|
||||||
|
|
||||||
C6821 m_6821;
|
C6821 m_6821;
|
||||||
|
|
||||||
|
@ -69,8 +75,8 @@ protected:
|
||||||
BYTE m_byState;
|
BYTE m_byState;
|
||||||
int m_nX;
|
int m_nX;
|
||||||
int m_nY;
|
int m_nY;
|
||||||
BOOL m_bBtn0;
|
bool m_bBtn0;
|
||||||
BOOL m_bBtn1;
|
bool m_bBtn1;
|
||||||
|
|
||||||
bool m_bVBL;
|
bool m_bVBL;
|
||||||
|
|
||||||
|
@ -83,12 +89,14 @@ protected:
|
||||||
int m_iMinY;
|
int m_iMinY;
|
||||||
int m_iMaxY;
|
int m_iMaxY;
|
||||||
|
|
||||||
BOOL m_bButtons[2];
|
bool m_bButtons[2];
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// todo: remove m_bActive:
|
||||||
|
// - instantiate CMouseInterface object when active (and delete when inactive)
|
||||||
bool m_bActive; // Mouse h/w is active within the Apple][ VM
|
bool m_bActive; // Mouse h/w is active within the Apple][ VM
|
||||||
bool m_bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w
|
bool m_bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w (m_bEnabled == true implies that m_bActive == true)
|
||||||
LPBYTE m_pSlotRom;
|
LPBYTE m_pSlotRom;
|
||||||
UINT m_uSlot;
|
UINT m_uSlot;
|
||||||
};
|
};
|
||||||
|
|
|
@ -99,7 +99,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
// Globals (Public) ___________________________________________________
|
// Globals (Public) ___________________________________________________
|
||||||
uint16_t g_nVideoClockVert = 0; // 9-bit: VC VB VA V5 V4 V3 V2 V1 V0 = 0 .. 262
|
uint16_t g_nVideoClockVert = 0; // 9-bit: VC VB VA V5 V4 V3 V2 V1 V0 = 0 .. 262
|
||||||
uint16_t g_nVideoClockHorz = 0; // 6-bit: H5 H4 H3 H2 H1 H0 = 0 .. 64, 25 >= visible
|
uint16_t g_nVideoClockHorz = 0; // 6-bit: H5 H4 H3 H2 H1 H0 = 0 .. 64, 25 >= visible (NB. final hpos is 2 cycles long, so a line is 65 cycles)
|
||||||
|
|
||||||
// Globals (Private) __________________________________________________
|
// Globals (Private) __________________________________________________
|
||||||
static int g_nVideoCharSet = 0;
|
static int g_nVideoCharSet = 0;
|
||||||
|
@ -1449,7 +1449,7 @@ void NTSC_SetVideoMode( int bVideoModeFlags )
|
||||||
g_aHorzClockVideoMode[ h ] = bVideoModeFlags;
|
g_aHorzClockVideoMode[ h ] = bVideoModeFlags;
|
||||||
|
|
||||||
g_nVideoMixed = bVideoModeFlags & VF_MIXED;
|
g_nVideoMixed = bVideoModeFlags & VF_MIXED;
|
||||||
g_nVideoCharSet = g_nAltCharSetOffset != 0;
|
g_nVideoCharSet = VideoGetSWAltCharSet() ? 1 : 0;
|
||||||
|
|
||||||
g_nTextPage = 1;
|
g_nTextPage = 1;
|
||||||
g_nHiresPage = 1;
|
g_nHiresPage = 1;
|
||||||
|
@ -1654,19 +1654,21 @@ void NTSC_VideoInit( uint8_t* pFramebuffer ) // wsVideoInit
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void NTSC_VideoInitAppleType ()
|
void NTSC_VideoInitAppleType ( DWORD cyclesThisFrame )
|
||||||
{
|
{
|
||||||
int model = g_Apple2Type;
|
int model = g_Apple2Type;
|
||||||
|
|
||||||
// anything other than low bit set means not II/II+
|
// anything other than low bit set means not II/II+ (TC: include Pravets machines too?)
|
||||||
if (model & 0xFFFE)
|
if (model & 0xFFFE)
|
||||||
g_pHorzClockOffset = APPLE_IIE_HORZ_CLOCK_OFFSET;
|
g_pHorzClockOffset = APPLE_IIE_HORZ_CLOCK_OFFSET;
|
||||||
else
|
else
|
||||||
g_pHorzClockOffset = APPLE_IIP_HORZ_CLOCK_OFFSET;
|
g_pHorzClockOffset = APPLE_IIP_HORZ_CLOCK_OFFSET;
|
||||||
|
|
||||||
g_nVideoClockVert = 0;
|
// TC: Move these to a better place (as init'ing these 2 vars is nothing to do with g_Apple2Type)
|
||||||
g_nVideoClockHorz = 0;
|
_ASSERT(cyclesThisFrame < VIDEO_SCANNER_6502_CYCLES);
|
||||||
|
if (cyclesThisFrame >= VIDEO_SCANNER_6502_CYCLES) cyclesThisFrame = 0; // error
|
||||||
|
g_nVideoClockVert = (uint16_t) (cyclesThisFrame / VIDEO_SCANNER_MAX_HORZ);
|
||||||
|
g_nVideoClockHorz = cyclesThisFrame % VIDEO_SCANNER_MAX_HORZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
extern uint32_t*NTSC_VideoGetChromaTable( bool bHueTypeMonochrome, bool bMonitorTypeColorTV );
|
extern uint32_t*NTSC_VideoGetChromaTable( bool bHueTypeMonochrome, bool bMonitorTypeColorTV );
|
||||||
extern uint16_t NTSC_VideoGetScannerAddress( unsigned long cycles6502 );
|
extern uint16_t NTSC_VideoGetScannerAddress( unsigned long cycles6502 );
|
||||||
extern void NTSC_VideoInit( uint8_t *pFramebuffer );
|
extern void NTSC_VideoInit( uint8_t *pFramebuffer );
|
||||||
extern void NTSC_VideoInitAppleType ();
|
extern void NTSC_VideoInitAppleType ( DWORD cyclesThisFrame );
|
||||||
extern void NTSC_VideoInitChroma();
|
extern void NTSC_VideoInitChroma();
|
||||||
extern bool NTSC_VideoIsVbl();
|
extern bool NTSC_VideoIsVbl();
|
||||||
extern void NTSC_VideoUpdateCycles( long cycles6502 );
|
extern void NTSC_VideoUpdateCycles( long cycles6502 );
|
||||||
|
|
|
@ -32,22 +32,24 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "ParallelPrinter.h"
|
#include "ParallelPrinter.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#include "..\resource\resource.h"
|
#include "..\resource\resource.h"
|
||||||
|
|
||||||
static DWORD inactivity = 0;
|
static DWORD inactivity = 0;
|
||||||
|
static unsigned int g_PrinterIdleLimit = 10;
|
||||||
static FILE* file = NULL;
|
static FILE* file = NULL;
|
||||||
DWORD const PRINTDRVR_SIZE = APPLE_SLOT_SIZE;
|
DWORD const PRINTDRVR_SIZE = APPLE_SLOT_SIZE;
|
||||||
TCHAR filepath[MAX_PATH * 2];
|
|
||||||
#define DEFAULT_PRINT_FILENAME "Printer.txt"
|
#define DEFAULT_PRINT_FILENAME "Printer.txt"
|
||||||
static char g_szPrintFilename[MAX_PATH] = {0};
|
static char g_szPrintFilename[MAX_PATH] = {0};
|
||||||
bool g_bDumpToPrinter = false;
|
bool g_bDumpToPrinter = false;
|
||||||
bool g_bConvertEncoding = true;
|
bool g_bConvertEncoding = true;
|
||||||
bool g_bFilterUnprintable = true;
|
bool g_bFilterUnprintable = true;
|
||||||
bool g_bPrinterAppend = false;
|
bool g_bPrinterAppend = false;
|
||||||
int g_iPrinterIdleLimit = 10;
|
|
||||||
bool g_bEnableDumpToRealPrinter = false;
|
bool g_bEnableDumpToRealPrinter = false;
|
||||||
|
|
||||||
|
static UINT g_uSlot = 0;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall PrintStatus(WORD, WORD, BYTE, BYTE, ULONG);
|
static BYTE __stdcall PrintStatus(WORD, WORD, BYTE, BYTE, ULONG);
|
||||||
|
@ -79,6 +81,8 @@ VOID PrintLoadRom(LPBYTE pCxRomPeripheral, const UINT uSlot)
|
||||||
//
|
//
|
||||||
|
|
||||||
RegisterIoHandler(uSlot, PrintStatus, PrintTransmit, NULL, NULL, NULL, NULL);
|
RegisterIoHandler(uSlot, PrintStatus, PrintTransmit, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
g_uSlot = uSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -242,11 +246,79 @@ void Printer_SetFilename(char* prtFilename)
|
||||||
|
|
||||||
unsigned int Printer_GetIdleLimit()
|
unsigned int Printer_GetIdleLimit()
|
||||||
{
|
{
|
||||||
return g_iPrinterIdleLimit;
|
return g_PrinterIdleLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
//unsigned int
|
|
||||||
void Printer_SetIdleLimit(unsigned int Duration)
|
void Printer_SetIdleLimit(unsigned int Duration)
|
||||||
{
|
{
|
||||||
g_iPrinterIdleLimit = Duration;
|
g_PrinterIdleLimit = Duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_CARD_PRINTER "Generic Printer"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_INACTIVITY "Inactivity"
|
||||||
|
#define SS_YAML_KEY_IDLELIMIT "Printer Idle Limit"
|
||||||
|
#define SS_YAML_KEY_FILENAME "Print Filename"
|
||||||
|
#define SS_YAML_KEY_FILEOPEN "Is File Open"
|
||||||
|
#define SS_YAML_KEY_DUMPTOPRINTER "Dump To Printer"
|
||||||
|
#define SS_YAML_KEY_CONVERTENCODING "Convert Encoding"
|
||||||
|
#define SS_YAML_KEY_FILTERUNPRINTABLE "Filter Unprintable"
|
||||||
|
#define SS_YAML_KEY_APPEND "Printer Append"
|
||||||
|
#define SS_YAML_KEY_DUMPTOREALPRINTER "Enable Dump To Real Printer"
|
||||||
|
|
||||||
|
std::string Printer_GetSnapshotCardName(void)
|
||||||
|
{
|
||||||
|
static const std::string name(SS_YAML_VALUE_CARD_PRINTER);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Slot slot(yamlSaveHelper, Printer_GetSnapshotCardName(), g_uSlot, 1);
|
||||||
|
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_INACTIVITY, inactivity);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IDLELIMIT, g_PrinterIdleLimit);
|
||||||
|
yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_szPrintFilename);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_FILEOPEN, (file != NULL) ? true : false);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_DUMPTOPRINTER, g_bDumpToPrinter);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_CONVERTENCODING, g_bConvertEncoding);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_FILTERUNPRINTABLE, g_bFilterUnprintable);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_APPEND, g_bPrinterAppend);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_DUMPTOREALPRINTER, g_bEnableDumpToRealPrinter);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||||
|
{
|
||||||
|
if (slot != 1) // fixme
|
||||||
|
throw std::string("Card: wrong slot");
|
||||||
|
|
||||||
|
if (version != 1)
|
||||||
|
throw std::string("Card: wrong version");
|
||||||
|
|
||||||
|
inactivity = yamlLoadHelper.LoadUint(SS_YAML_KEY_INACTIVITY);
|
||||||
|
g_PrinterIdleLimit = yamlLoadHelper.LoadUint(SS_YAML_KEY_IDLELIMIT);
|
||||||
|
strncpy(g_szPrintFilename, yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME).c_str(), sizeof(g_szPrintFilename));
|
||||||
|
|
||||||
|
if (yamlLoadHelper.LoadBool(SS_YAML_KEY_FILEOPEN))
|
||||||
|
{
|
||||||
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_APPEND); // Consume
|
||||||
|
g_bPrinterAppend = true; // Re-open print-file in append mode
|
||||||
|
BOOL bRes = CheckPrint();
|
||||||
|
if (!bRes)
|
||||||
|
throw std::string("Printer Card: Unable to resume printing to file");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_bPrinterAppend = yamlLoadHelper.LoadBool(SS_YAML_KEY_APPEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_bDumpToPrinter = yamlLoadHelper.LoadBool(SS_YAML_KEY_DUMPTOPRINTER);
|
||||||
|
g_bConvertEncoding = yamlLoadHelper.LoadBool(SS_YAML_KEY_CONVERTENCODING);
|
||||||
|
g_bFilterUnprintable = yamlLoadHelper.LoadBool(SS_YAML_KEY_FILTERUNPRINTABLE);
|
||||||
|
g_bEnableDumpToRealPrinter = yamlLoadHelper.LoadBool(SS_YAML_KEY_DUMPTOREALPRINTER);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,12 @@ char* Printer_GetFilename();
|
||||||
void Printer_SetIdleLimit(unsigned int Duration);
|
void Printer_SetIdleLimit(unsigned int Duration);
|
||||||
unsigned int Printer_GetIdleLimit();
|
unsigned int Printer_GetIdleLimit();
|
||||||
|
|
||||||
|
std::string Printer_GetSnapshotCardName(void);
|
||||||
|
void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||||
|
|
||||||
extern bool g_bDumpToPrinter;
|
extern bool g_bDumpToPrinter;
|
||||||
extern bool g_bConvertEncoding;
|
extern bool g_bConvertEncoding;
|
||||||
extern bool g_bFilterUnprintable;
|
extern bool g_bFilterUnprintable;
|
||||||
extern bool g_bPrinterAppend;
|
extern bool g_bPrinterAppend;
|
||||||
extern int g_iPrinterIdleLimit;
|
|
||||||
extern bool g_bFilterUnprintable;
|
|
||||||
extern bool g_bPrinterAppend;
|
|
||||||
extern bool g_bEnableDumpToRealPrinter; // Set by cmd-line: -printer-real
|
extern bool g_bEnableDumpToRealPrinter; // Set by cmd-line: -printer-real
|
||||||
|
|
48
source/Pravets.cpp
Normal file
48
source/Pravets.cpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
AppleWin : An Apple //e emulator for Windows
|
||||||
|
|
||||||
|
Copyright (C) 1994-1996, Michael O'Brien
|
||||||
|
Copyright (C) 1999-2001, Oliver Schmidt
|
||||||
|
Copyright (C) 2002-2005, Tom Charlesworth
|
||||||
|
Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski
|
||||||
|
|
||||||
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
AppleWin is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with AppleWin; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Description: Pravets - Apple II clone
|
||||||
|
*
|
||||||
|
* Author: Various
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "AppleWin.h"
|
||||||
|
#include "Frame.h"
|
||||||
|
#include "Keyboard.h"
|
||||||
|
#include "Tape.h"
|
||||||
|
|
||||||
|
//Pravets 8A/C variables
|
||||||
|
bool P8CAPS_ON = false;
|
||||||
|
bool P8Shift = false;
|
||||||
|
|
||||||
|
void PravetsReset(void)
|
||||||
|
{
|
||||||
|
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
||||||
|
{
|
||||||
|
P8CAPS_ON = false;
|
||||||
|
TapeWrite(0, 0, 0, 0 ,0);
|
||||||
|
FrameRefreshStatus(DRAW_LEDS);
|
||||||
|
}
|
||||||
|
}
|
7
source/Pravets.h
Normal file
7
source/Pravets.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//Pravets 8A/C only variables
|
||||||
|
extern bool P8CAPS_ON;
|
||||||
|
extern bool P8Shift;
|
||||||
|
|
||||||
|
void PravetsReset(void);
|
93
source/SAM.cpp
Normal file
93
source/SAM.cpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
AppleWin : An Apple //e emulator for Windows
|
||||||
|
|
||||||
|
Copyright (C) 1994-1996, Michael O'Brien
|
||||||
|
Copyright (C) 1999-2001, Oliver Schmidt
|
||||||
|
Copyright (C) 2002-2005, Tom Charlesworth
|
||||||
|
Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
|
||||||
|
|
||||||
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
AppleWin is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with AppleWin; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
SAM.CPP
|
||||||
|
|
||||||
|
Emulate an 8 bit DAC (eg: SAM card) which writes unsigned byte
|
||||||
|
data written to its IO area to the audio buffer (as used by the speaker).
|
||||||
|
This merges the data with the speaker stream, reducing the volume
|
||||||
|
of the Apple speaker when active.
|
||||||
|
|
||||||
|
Riccardo Macri Mar 2015
|
||||||
|
*/
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "AppleWin.h"
|
||||||
|
#include "Memory.h"
|
||||||
|
#include "SAM.h"
|
||||||
|
#include "Speaker.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Write 8 bit data to speaker. Emulates a "SAM" speech card DAC
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
static BYTE __stdcall IOWrite_SAM(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
||||||
|
{
|
||||||
|
// Emulate audio from a SAM / 8 bit DAC card
|
||||||
|
// Only supportable if AppleWin is using WAVE output
|
||||||
|
//
|
||||||
|
// This works by using the existing speaker handling but then
|
||||||
|
// replacing the speaker audio with the 8 bit samples from the DAC
|
||||||
|
// before they get sent out to the soundcard buffer, whilst
|
||||||
|
// audio samples are being written to the SAM.
|
||||||
|
//
|
||||||
|
// Whilst very unusual, it is possible to intermingle use of SAM and the apple
|
||||||
|
// speaker. This is crudely supported with g_bQuieterSpeaker making the Apple
|
||||||
|
// speaker produce quieter clicks which will be crudely intermingled
|
||||||
|
// with the SAM data. The mute gets reset after the speaker code detects
|
||||||
|
// silence.
|
||||||
|
|
||||||
|
if (soundtype != SOUND_WAVE)
|
||||||
|
return MemReadFloatingBus(nCyclesLeft);
|
||||||
|
|
||||||
|
// use existing speaker code to bring timing up to date
|
||||||
|
BYTE res = SpkrToggle(pc, addr, bWrite, d, nCyclesLeft);
|
||||||
|
|
||||||
|
// The DAC in the SAM uses unsigned 8 bit samples
|
||||||
|
// The WAV data that g_nSpeakerData is loaded into is a signed short
|
||||||
|
//
|
||||||
|
// We convert unsigned 8 bit to signed by toggling the most significant bit
|
||||||
|
//
|
||||||
|
// SAM card WAV driver SAM WAV
|
||||||
|
// 0xFF 255 0x7f 127 _ FF 7F
|
||||||
|
// 0x81 129 0x01 1 / \
|
||||||
|
// 0x80 128 0x00 0 / \ /80 00
|
||||||
|
// 0x7f 127 0xFF -1 \_/
|
||||||
|
// 0x00 0 0x80 -128 00 80
|
||||||
|
//
|
||||||
|
// SAM is 8 bit, PC WAV is 16 so shift audio to the MSB (<< 8)
|
||||||
|
|
||||||
|
g_nSpeakerData = (d ^ 0x80) << 8;
|
||||||
|
|
||||||
|
// make speaker quieter so eg: a metronome click through the
|
||||||
|
// Apple speaker is softer vs. the analogue SAM output.
|
||||||
|
g_bQuieterSpeaker = true;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureSAM(LPBYTE pCxRomPeripheral, UINT uSlot)
|
||||||
|
{
|
||||||
|
RegisterIoHandler(uSlot, IO_Null, IOWrite_SAM, IO_Null, IO_Null, NULL, NULL);
|
||||||
|
}
|
3
source/SAM.h
Normal file
3
source/SAM.h
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void ConfigureSAM(LPBYTE pCxRomPeripheral, UINT uSlot);
|
|
@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows
|
||||||
Copyright (C) 1994-1996, Michael O'Brien
|
Copyright (C) 1994-1996, Michael O'Brien
|
||||||
Copyright (C) 1999-2001, Oliver Schmidt
|
Copyright (C) 1999-2001, Oliver Schmidt
|
||||||
Copyright (C) 2002-2005, Tom Charlesworth
|
Copyright (C) 2002-2005, Tom Charlesworth
|
||||||
Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
|
Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski
|
||||||
|
|
||||||
AppleWin is free software; you can redistribute it and/or modify
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -23,11 +23,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
/* Description: Save-state (snapshot) module
|
/* Description: Save-state (snapshot) module
|
||||||
*
|
*
|
||||||
* Author: Copyright (c) 2004-2006 Tom Charlesworth
|
* Author: Copyright (c) 2004-2015 Tom Charlesworth
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "SaveState_Structs_v1.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#include "AppleWin.h"
|
#include "AppleWin.h"
|
||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
#include "Disk.h"
|
#include "Disk.h"
|
||||||
|
@ -36,17 +39,20 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Mockingboard.h"
|
#include "Mockingboard.h"
|
||||||
|
#include "MouseInterface.h"
|
||||||
|
#include "ParallelPrinter.h"
|
||||||
|
#include "Pravets.h"
|
||||||
#include "SerialComms.h"
|
#include "SerialComms.h"
|
||||||
#include "Speaker.h"
|
#include "Speaker.h"
|
||||||
|
#include "Speech.h"
|
||||||
#include "Video.h"
|
#include "Video.h"
|
||||||
|
#include "z80emu.h"
|
||||||
|
|
||||||
// Prototypes (Public)
|
#include "Configuration\Config.h"
|
||||||
// Note: This is here and not in Video.h to prevent header include bloat.
|
#include "Configuration\IPropertySheet.h"
|
||||||
// i.e. so we don't need to incude "Structs.h" for NTSC.cpp
|
|
||||||
DWORD VideoGetSnapshot(SS_IO_Video* pSS);
|
|
||||||
DWORD VideoSetSnapshot(SS_IO_Video* pSS);
|
|
||||||
|
|
||||||
#define DEFAULT_SNAPSHOT_NAME "SaveState.aws"
|
|
||||||
|
#define DEFAULT_SNAPSHOT_NAME "SaveState.aws.yaml"
|
||||||
|
|
||||||
bool g_bSaveStateOnExit = false;
|
bool g_bSaveStateOnExit = false;
|
||||||
|
|
||||||
|
@ -54,6 +60,13 @@ static std::string g_strSaveStateFilename;
|
||||||
static std::string g_strSaveStatePathname;
|
static std::string g_strSaveStatePathname;
|
||||||
static std::string g_strSaveStatePath;
|
static std::string g_strSaveStatePath;
|
||||||
|
|
||||||
|
static YamlHelper yamlHelper;
|
||||||
|
|
||||||
|
#define SS_FILE_VER 2
|
||||||
|
|
||||||
|
#define UNIT_APPLE2_VER 1
|
||||||
|
#define UNIT_SLOTS_VER 1
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void Snapshot_SetFilename(std::string strPathname)
|
void Snapshot_SetFilename(std::string strPathname)
|
||||||
|
@ -98,22 +111,27 @@ const char* Snapshot_GetPath()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void Snapshot_LoadState()
|
static void Snapshot_LoadState_v1() // .aws v1.0.0.1, up to (and including) AppleWin v1.25.0
|
||||||
{
|
{
|
||||||
char szMessage[32 + MAX_PATH];
|
std::string strOldImageDir(g_sCurrentDir);
|
||||||
std::string strOldImageDir;
|
|
||||||
|
|
||||||
APPLEWIN_SNAPSHOT* pSS = (APPLEWIN_SNAPSHOT*) new char[sizeof(APPLEWIN_SNAPSHOT)];
|
APPLEWIN_SNAPSHOT_v1* pSS = (APPLEWIN_SNAPSHOT_v1*) new char[sizeof(APPLEWIN_SNAPSHOT_v1)]; // throw's bad_alloc
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
strOldImageDir = g_sCurrentDir;
|
#if _MSC_VER >= 1600 // static_assert supported from VS2010 (cl.exe v16.00)
|
||||||
|
static_assert(kSnapshotSize_v1 == sizeof(APPLEWIN_SNAPSHOT_v1), "Save-state v1 struct size mismatch");
|
||||||
|
#else
|
||||||
|
// A compile error here means sizeof(APPLEWIN_SNAPSHOT_v1) is wrong, eg. one of the constituent structs has been modified
|
||||||
|
typedef char VerifySizesAreEqual[kSnapshotSize_v1 == sizeof(APPLEWIN_SNAPSHOT_v1) ? 1 : -1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (kSnapshotSize_v1 != sizeof(APPLEWIN_SNAPSHOT_v1))
|
||||||
|
throw std::string("Save-state v1 struct size mismatch");
|
||||||
|
|
||||||
SetCurrentImageDir(g_strSaveStatePath.c_str()); // Allow .dsk's load without prompting
|
SetCurrentImageDir(g_strSaveStatePath.c_str()); // Allow .dsk's load without prompting
|
||||||
|
|
||||||
if(pSS == NULL)
|
memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT_v1));
|
||||||
throw(0);
|
|
||||||
|
|
||||||
memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -126,49 +144,32 @@ void Snapshot_LoadState()
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if(hFile == INVALID_HANDLE_VALUE)
|
if(hFile == INVALID_HANDLE_VALUE)
|
||||||
{
|
throw std::string("File not found: ") + g_strSaveStatePathname;
|
||||||
strcpy(szMessage, "File not found: ");
|
|
||||||
strcpy(szMessage + strlen(szMessage), g_strSaveStatePathname.c_str());
|
|
||||||
throw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD dwBytesRead;
|
DWORD dwBytesRead;
|
||||||
BOOL bRes = ReadFile( hFile,
|
BOOL bRes = ReadFile( hFile,
|
||||||
pSS,
|
pSS,
|
||||||
sizeof(APPLEWIN_SNAPSHOT),
|
sizeof(APPLEWIN_SNAPSHOT_v1),
|
||||||
&dwBytesRead,
|
&dwBytesRead,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
|
|
||||||
if(!bRes || (dwBytesRead != sizeof(APPLEWIN_SNAPSHOT)))
|
if(!bRes || (dwBytesRead != sizeof(APPLEWIN_SNAPSHOT_v1)))
|
||||||
{
|
|
||||||
// File size wrong: probably because of version mismatch or corrupt file
|
// File size wrong: probably because of version mismatch or corrupt file
|
||||||
strcpy(szMessage, "File size mismatch");
|
throw std::string("File size mismatch");
|
||||||
throw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pSS->Hdr.dwTag != AW_SS_TAG)
|
if(pSS->Hdr.dwTag != AW_SS_TAG)
|
||||||
{
|
throw std::string("File corrupt");
|
||||||
strcpy(szMessage, "File corrupt");
|
|
||||||
throw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pSS->Hdr.dwVersion != MAKE_VERSION(1,0,0,1))
|
if(pSS->Hdr.dwVersion != MAKE_VERSION(1,0,0,1))
|
||||||
{
|
throw std::string("Version mismatch");
|
||||||
strcpy(szMessage, "Version mismatch");
|
|
||||||
throw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TO DO: Verify checksum
|
// TO DO: Verify checksum
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reset all sub-systems
|
// Reset all sub-systems
|
||||||
MemReset();
|
MemReset();
|
||||||
|
|
||||||
if (!IS_APPLE2)
|
|
||||||
MemResetPaging();
|
|
||||||
|
|
||||||
DiskReset();
|
DiskReset();
|
||||||
KeybReset();
|
KeybReset();
|
||||||
VideoResetState();
|
VideoResetState();
|
||||||
|
@ -178,38 +179,46 @@ void Snapshot_LoadState()
|
||||||
// Apple2 unit
|
// Apple2 unit
|
||||||
//
|
//
|
||||||
|
|
||||||
CpuSetSnapshot(&pSS->Apple2Unit.CPU6502);
|
SS_CPU6502& CPU = pSS->Apple2Unit.CPU6502;
|
||||||
sg_SSC.CommSetSnapshot(&pSS->Apple2Unit.Comms);
|
CpuSetSnapshot_v1(CPU.A, CPU.X, CPU.Y, CPU.P, CPU.S, CPU.PC, CPU.nCumulativeCycles);
|
||||||
JoySetSnapshot(&pSS->Apple2Unit.Joystick);
|
|
||||||
KeybSetSnapshot(&pSS->Apple2Unit.Keyboard);
|
SS_IO_Comms& SSC = pSS->Apple2Unit.Comms;
|
||||||
SpkrSetSnapshot(&pSS->Apple2Unit.Speaker);
|
sg_SSC.SetSnapshot_v1(SSC.baudrate, SSC.bytesize, SSC.commandbyte, SSC.comminactivity, SSC.controlbyte, SSC.parity, SSC.stopbits);
|
||||||
VideoSetSnapshot(&pSS->Apple2Unit.Video);
|
|
||||||
MemSetSnapshot(&pSS->Apple2Unit.Memory);
|
JoySetSnapshot_v1(pSS->Apple2Unit.Joystick.nJoyCntrResetCycle);
|
||||||
|
KeybSetSnapshot_v1(pSS->Apple2Unit.Keyboard.nLastKey);
|
||||||
|
SpkrSetSnapshot_v1(pSS->Apple2Unit.Speaker.nSpkrLastCycle);
|
||||||
|
VideoSetSnapshot_v1(pSS->Apple2Unit.Video.bAltCharSet, pSS->Apple2Unit.Video.dwVidMode);
|
||||||
|
MemSetSnapshot_v1(pSS->Apple2Unit.Memory.dwMemMode, pSS->Apple2Unit.Memory.bLastWriteRam, pSS->Apple2Unit.Memory.nMemMain, pSS->Apple2Unit.Memory.nMemAux);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Slot4: Mockingboard
|
// Slot4: Mockingboard
|
||||||
MB_SetSnapshot(&pSS->Mockingboard1, 4);
|
MB_SetSnapshot_v1(&pSS->Mockingboard1, 4);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Slot5: Mockingboard
|
// Slot5: Mockingboard
|
||||||
MB_SetSnapshot(&pSS->Mockingboard2, 5);
|
MB_SetSnapshot_v1(&pSS->Mockingboard2, 5);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Slot6: Disk][
|
// Slot6: Disk][
|
||||||
DiskSetSnapshot(&pSS->Disk2, 6);
|
DiskSetSnapshot_v1(&pSS->Disk2);
|
||||||
|
|
||||||
SetLoadedSaveStateFlag(true);
|
SetLoadedSaveStateFlag(true);
|
||||||
|
|
||||||
|
MemUpdatePaging(TRUE);
|
||||||
}
|
}
|
||||||
catch(int)
|
catch(std::string szMessage)
|
||||||
{
|
{
|
||||||
MessageBox( g_hFrameWindow,
|
MessageBox( g_hFrameWindow,
|
||||||
szMessage,
|
szMessage.c_str(),
|
||||||
TEXT("Load State"),
|
TEXT("Load State"),
|
||||||
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
||||||
|
|
||||||
SetCurrentImageDir(strOldImageDir.c_str());
|
SetCurrentImageDir(strOldImageDir.c_str());
|
||||||
|
|
||||||
|
PostMessage(g_hFrameWindow, WM_USER_RESTART, 0, 0); // Power-cycle VM (undoing all the new state just loaded)
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] pSS;
|
delete [] pSS;
|
||||||
|
@ -217,104 +226,393 @@ void Snapshot_LoadState()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void Snapshot_SaveState()
|
static HANDLE m_hFile = INVALID_HANDLE_VALUE;
|
||||||
|
static CConfigNeedingRestart m_ConfigNew;
|
||||||
|
|
||||||
|
static std::string GetSnapshotUnitApple2Name(void)
|
||||||
{
|
{
|
||||||
APPLEWIN_SNAPSHOT* pSS = (APPLEWIN_SNAPSHOT*) new char[sizeof(APPLEWIN_SNAPSHOT)];
|
static const std::string name("Apple2");
|
||||||
if(pSS == NULL)
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string GetSnapshotUnitSlotsName(void)
|
||||||
|
{
|
||||||
|
static const std::string name("Slots");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_MODEL "Model"
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_APPLE2 "Apple]["
|
||||||
|
#define SS_YAML_VALUE_APPLE2PLUS "Apple][+"
|
||||||
|
#define SS_YAML_VALUE_APPLE2E "Apple//e"
|
||||||
|
#define SS_YAML_VALUE_APPLE2EENHANCED "Enhanced Apple//e"
|
||||||
|
#define SS_YAML_VALUE_APPLE2C "Apple2c"
|
||||||
|
#define SS_YAML_VALUE_PRAVETS82 "Pravets82"
|
||||||
|
#define SS_YAML_VALUE_PRAVETS8M "Pravets8M"
|
||||||
|
#define SS_YAML_VALUE_PRAVETS8A "Pravets8A"
|
||||||
|
|
||||||
|
static eApple2Type ParseApple2Type(std::string type)
|
||||||
|
{
|
||||||
|
if (type == SS_YAML_VALUE_APPLE2) return A2TYPE_APPLE2;
|
||||||
|
else if (type == SS_YAML_VALUE_APPLE2PLUS) return A2TYPE_APPLE2PLUS;
|
||||||
|
else if (type == SS_YAML_VALUE_APPLE2E) return A2TYPE_APPLE2E;
|
||||||
|
else if (type == SS_YAML_VALUE_APPLE2EENHANCED) return A2TYPE_APPLE2EENHANCED;
|
||||||
|
else if (type == SS_YAML_VALUE_APPLE2C) return A2TYPE_APPLE2C;
|
||||||
|
else if (type == SS_YAML_VALUE_PRAVETS82) return A2TYPE_PRAVETS82;
|
||||||
|
else if (type == SS_YAML_VALUE_PRAVETS8M) return A2TYPE_PRAVETS8M;
|
||||||
|
else if (type == SS_YAML_VALUE_PRAVETS8A) return A2TYPE_PRAVETS8A;
|
||||||
|
|
||||||
|
throw std::string("Load: Unknown Apple2 type");
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string GetApple2TypeAsString(void)
|
||||||
|
{
|
||||||
|
switch ( GetApple2Type() )
|
||||||
{
|
{
|
||||||
// To do
|
case A2TYPE_APPLE2: return SS_YAML_VALUE_APPLE2;
|
||||||
return;
|
case A2TYPE_APPLE2PLUS: return SS_YAML_VALUE_APPLE2PLUS;
|
||||||
|
case A2TYPE_APPLE2E: return SS_YAML_VALUE_APPLE2E;
|
||||||
|
case A2TYPE_APPLE2EENHANCED:return SS_YAML_VALUE_APPLE2EENHANCED;
|
||||||
|
case A2TYPE_APPLE2C: return SS_YAML_VALUE_APPLE2C;
|
||||||
|
case A2TYPE_PRAVETS82: return SS_YAML_VALUE_PRAVETS82;
|
||||||
|
case A2TYPE_PRAVETS8M: return SS_YAML_VALUE_PRAVETS8M;
|
||||||
|
case A2TYPE_PRAVETS8A: return SS_YAML_VALUE_PRAVETS8A;
|
||||||
|
default:
|
||||||
|
throw std::string("Save: Unknown Apple2 type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
|
static UINT ParseFileHdr(void)
|
||||||
|
{
|
||||||
|
std::string scalar;
|
||||||
|
if (!yamlHelper.GetScalar(scalar))
|
||||||
|
throw std::string(SS_YAML_KEY_FILEHDR ": Failed to find scalar");
|
||||||
|
|
||||||
|
if (scalar != SS_YAML_KEY_FILEHDR)
|
||||||
|
throw std::string("Failed to find file header");
|
||||||
|
|
||||||
|
yamlHelper.GetMapStartEvent();
|
||||||
|
|
||||||
|
YamlLoadHelper yamlLoadHelper(yamlHelper);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
std::string value = yamlLoadHelper.LoadString(SS_YAML_KEY_TAG);
|
||||||
|
if (value != SS_YAML_VALUE_AWSS)
|
||||||
|
{
|
||||||
|
//printf("%s: Bad tag (%s) - expected %s\n", SS_YAML_KEY_FILEHDR, value.c_str(), SS_YAML_VALUE_AWSS);
|
||||||
|
throw std::string(SS_YAML_KEY_FILEHDR ": Bad tag");
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT));
|
return yamlLoadHelper.LoadUint(SS_YAML_KEY_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
pSS->Hdr.dwTag = AW_SS_TAG;
|
//---
|
||||||
pSS->Hdr.dwVersion = MAKE_VERSION(1,0,0,1);
|
|
||||||
pSS->Hdr.dwChecksum = 0; // TO DO
|
|
||||||
|
|
||||||
//
|
static void ParseUnitApple2(YamlLoadHelper& yamlLoadHelper, UINT version)
|
||||||
// Apple2 unit
|
{
|
||||||
//
|
if (version != UNIT_APPLE2_VER)
|
||||||
|
throw std::string(SS_YAML_KEY_UNIT ": Apple2: Version mismatch");
|
||||||
|
|
||||||
pSS->Apple2Unit.UnitHdr.dwLength = sizeof(SS_APPLE2_Unit);
|
std::string model = yamlLoadHelper.LoadString(SS_YAML_KEY_MODEL);
|
||||||
pSS->Apple2Unit.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
SetApple2Type( ParseApple2Type(model) ); // NB. Sets default main CPU type
|
||||||
|
m_ConfigNew.m_Apple2Type = GetApple2Type();
|
||||||
|
|
||||||
CpuGetSnapshot(&pSS->Apple2Unit.CPU6502);
|
CpuLoadSnapshot(yamlLoadHelper); // NB. Overrides default main CPU type
|
||||||
sg_SSC.CommGetSnapshot(&pSS->Apple2Unit.Comms);
|
m_ConfigNew.m_CpuType = GetMainCpu();
|
||||||
JoyGetSnapshot(&pSS->Apple2Unit.Joystick);
|
|
||||||
KeybGetSnapshot(&pSS->Apple2Unit.Keyboard);
|
|
||||||
SpkrGetSnapshot(&pSS->Apple2Unit.Speaker);
|
|
||||||
VideoGetSnapshot(&pSS->Apple2Unit.Video);
|
|
||||||
MemGetSnapshot(&pSS->Apple2Unit.Memory);
|
|
||||||
|
|
||||||
//
|
JoyLoadSnapshot(yamlLoadHelper);
|
||||||
// Slot1: Empty
|
KeybLoadSnapshot(yamlLoadHelper);
|
||||||
pSS->Empty1.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY);
|
SpkrLoadSnapshot(yamlLoadHelper);
|
||||||
pSS->Empty1.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
VideoLoadSnapshot(yamlLoadHelper);
|
||||||
pSS->Empty1.Hdr.dwSlot = 1;
|
MemLoadSnapshot(yamlLoadHelper);
|
||||||
pSS->Empty1.Hdr.dwType = CT_Empty;
|
}
|
||||||
|
|
||||||
//
|
//---
|
||||||
// Slot2: Empty
|
|
||||||
pSS->Empty2.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY);
|
|
||||||
pSS->Empty2.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
|
||||||
pSS->Empty2.Hdr.dwSlot = 2;
|
|
||||||
pSS->Empty2.Hdr.dwType = CT_Empty;
|
|
||||||
|
|
||||||
//
|
static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT version)
|
||||||
// Slot3: Empty
|
{
|
||||||
pSS->Empty3.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY);
|
if (version != UNIT_SLOTS_VER)
|
||||||
pSS->Empty3.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0);
|
throw std::string(SS_YAML_KEY_UNIT ": Slots: Version mismatch");
|
||||||
pSS->Empty3.Hdr.dwSlot = 3;
|
|
||||||
pSS->Empty3.Hdr.dwType = CT_Empty;
|
|
||||||
|
|
||||||
//
|
while (1)
|
||||||
// Slot4: Mockingboard
|
|
||||||
MB_GetSnapshot(&pSS->Mockingboard1, 4);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Slot5: Mockingboard
|
|
||||||
MB_GetSnapshot(&pSS->Mockingboard2, 5);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Slot6: Disk][
|
|
||||||
DiskGetSnapshot(&pSS->Disk2, 6);
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
HANDLE hFile = CreateFile( g_strSaveStatePathname.c_str(),
|
|
||||||
GENERIC_WRITE,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
CREATE_ALWAYS,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
DWORD dwError = GetLastError();
|
|
||||||
_ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS));
|
|
||||||
|
|
||||||
if(hFile != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
{
|
||||||
DWORD dwBytesWritten;
|
std::string scalar = yamlLoadHelper.GetMapNextSlotNumber();
|
||||||
BOOL bRes = WriteFile( hFile,
|
if (scalar.empty())
|
||||||
pSS,
|
break; // done all slots
|
||||||
sizeof(APPLEWIN_SNAPSHOT),
|
|
||||||
&dwBytesWritten,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if(!bRes || (dwBytesWritten != sizeof(APPLEWIN_SNAPSHOT)))
|
const int slot = strtoul(scalar.c_str(), NULL, 10); // NB. aux slot supported as a different "unit"
|
||||||
dwError = GetLastError();
|
if (slot < 1 || slot > 7)
|
||||||
|
throw std::string("Slots: Invalid slot #: ") + scalar;
|
||||||
|
|
||||||
CloseHandle(hFile);
|
yamlLoadHelper.GetSubMap(scalar);
|
||||||
|
|
||||||
|
std::string card = yamlLoadHelper.LoadString(SS_YAML_KEY_CARD);
|
||||||
|
UINT version = yamlLoadHelper.LoadUint(SS_YAML_KEY_VERSION);
|
||||||
|
|
||||||
|
if (!yamlLoadHelper.GetSubMap(std::string(SS_YAML_KEY_STATE)))
|
||||||
|
throw std::string(SS_YAML_KEY_UNIT ": Expected sub-map name: " SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
|
bool bIsCardSupported = true;
|
||||||
|
SS_CARDTYPE type = CT_Empty;
|
||||||
|
bool bRes = false;
|
||||||
|
|
||||||
|
if (card == Printer_GetSnapshotCardName())
|
||||||
|
{
|
||||||
|
bRes = Printer_LoadSnapshot(yamlLoadHelper, slot, version);
|
||||||
|
type = CT_GenericPrinter;
|
||||||
|
}
|
||||||
|
else if (card == sg_SSC.GetSnapshotCardName())
|
||||||
|
{
|
||||||
|
bRes = sg_SSC.LoadSnapshot(yamlLoadHelper, slot, version);
|
||||||
|
type = CT_SSC;
|
||||||
|
}
|
||||||
|
else if (card == sg_Mouse.GetSnapshotCardName())
|
||||||
|
{
|
||||||
|
bRes = sg_Mouse.LoadSnapshot(yamlLoadHelper, slot, version);
|
||||||
|
type = CT_MouseInterface;
|
||||||
|
}
|
||||||
|
else if (card == Z80_GetSnapshotCardName())
|
||||||
|
{
|
||||||
|
bRes = Z80_LoadSnapshot(yamlLoadHelper, slot, version);
|
||||||
|
type = CT_Z80;
|
||||||
|
}
|
||||||
|
else if (card == MB_GetSnapshotCardName())
|
||||||
|
{
|
||||||
|
bRes = MB_LoadSnapshot(yamlLoadHelper, slot, version);
|
||||||
|
type = CT_MockingboardC;
|
||||||
|
}
|
||||||
|
else if (card == Phasor_GetSnapshotCardName())
|
||||||
|
{
|
||||||
|
bRes = Phasor_LoadSnapshot(yamlLoadHelper, slot, version);
|
||||||
|
type = CT_Phasor;
|
||||||
|
}
|
||||||
|
else if (card == DiskGetSnapshotCardName())
|
||||||
|
{
|
||||||
|
bRes = DiskLoadSnapshot(yamlLoadHelper, slot, version);
|
||||||
|
type = CT_Disk2;
|
||||||
|
}
|
||||||
|
else if (card == HD_GetSnapshotCardName())
|
||||||
|
{
|
||||||
|
bRes = HD_LoadSnapshot(yamlLoadHelper, slot, version, g_strSaveStatePath);
|
||||||
|
m_ConfigNew.m_bEnableHDD = true;
|
||||||
|
type = CT_GenericHDD;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dwError = GetLastError();
|
bIsCardSupported = false;
|
||||||
|
throw std::string("Slots: Unknown card: " + card); // todo: don't throw - just ignore & continue
|
||||||
}
|
}
|
||||||
|
|
||||||
_ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS));
|
if (bRes && bIsCardSupported)
|
||||||
|
{
|
||||||
|
m_ConfigNew.m_Slot[slot] = type;
|
||||||
|
}
|
||||||
|
|
||||||
delete [] pSS;
|
yamlLoadHelper.PopMap();
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
|
||||||
|
static void ParseUnit(void)
|
||||||
|
{
|
||||||
|
yamlHelper.GetMapStartEvent();
|
||||||
|
|
||||||
|
YamlLoadHelper yamlLoadHelper(yamlHelper);
|
||||||
|
|
||||||
|
std::string unit = yamlLoadHelper.LoadString(SS_YAML_KEY_TYPE);
|
||||||
|
UINT version = yamlLoadHelper.LoadUint(SS_YAML_KEY_VERSION);
|
||||||
|
|
||||||
|
if (!yamlLoadHelper.GetSubMap(std::string(SS_YAML_KEY_STATE)))
|
||||||
|
throw std::string(SS_YAML_KEY_UNIT ": Expected sub-map name: " SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
|
if (unit == GetSnapshotUnitApple2Name())
|
||||||
|
{
|
||||||
|
ParseUnitApple2(yamlLoadHelper, version);
|
||||||
|
}
|
||||||
|
else if (unit == MemGetSnapshotUnitAuxSlotName())
|
||||||
|
{
|
||||||
|
MemLoadSnapshotAux(yamlLoadHelper, version);
|
||||||
|
}
|
||||||
|
else if (unit == GetSnapshotUnitSlotsName())
|
||||||
|
{
|
||||||
|
ParseSlots(yamlLoadHelper, version);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::string(SS_YAML_KEY_UNIT ": Unknown type: " ) + unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Snapshot_LoadState_v2(void)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int res = yamlHelper.InitParser( g_strSaveStatePathname.c_str() );
|
||||||
|
if (!res)
|
||||||
|
throw std::string("Failed to initialize parser or open file"); // TODO: disambiguate
|
||||||
|
|
||||||
|
UINT version = ParseFileHdr();
|
||||||
|
if (version != SS_FILE_VER)
|
||||||
|
throw std::string("Version mismatch");
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
CConfigNeedingRestart ConfigOld;
|
||||||
|
ConfigOld.m_Slot[1] = CT_GenericPrinter; // fixme
|
||||||
|
ConfigOld.m_Slot[2] = CT_SSC; // fixme
|
||||||
|
//ConfigOld.m_Slot[3] = CT_Uthernet; // todo
|
||||||
|
ConfigOld.m_Slot[6] = CT_Disk2; // fixme
|
||||||
|
ConfigOld.m_Slot[7] = ConfigOld.m_bEnableHDD ? CT_GenericHDD : CT_Empty; // fixme
|
||||||
|
//ConfigOld.m_SlotAux = ?; // fixme
|
||||||
|
|
||||||
|
for (UINT i=0; i<NUM_SLOTS; i++)
|
||||||
|
m_ConfigNew.m_Slot[i] = CT_Empty;
|
||||||
|
m_ConfigNew.m_SlotAux = CT_Empty;
|
||||||
|
m_ConfigNew.m_bEnableHDD = false;
|
||||||
|
//m_ConfigNew.m_bEnableTheFreezesF8Rom = ?; // todo: when support saving config
|
||||||
|
//m_ConfigNew.m_bEnhanceDisk = ?; // todo: when support saving config
|
||||||
|
|
||||||
|
MemReset();
|
||||||
|
PravetsReset();
|
||||||
|
DiskReset();
|
||||||
|
KeybReset();
|
||||||
|
VideoResetState();
|
||||||
|
MB_Reset();
|
||||||
|
#ifdef USE_SPEECH_API
|
||||||
|
g_Speech.Reset();
|
||||||
|
#endif
|
||||||
|
sg_Mouse.Uninitialize();
|
||||||
|
sg_Mouse.Reset();
|
||||||
|
HD_SetEnabled(false);
|
||||||
|
|
||||||
|
std::string scalar;
|
||||||
|
while(yamlHelper.GetScalar(scalar))
|
||||||
|
{
|
||||||
|
if (scalar == SS_YAML_KEY_UNIT)
|
||||||
|
ParseUnit();
|
||||||
|
else
|
||||||
|
throw std::string("Unknown top-level scalar: " + scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLoadedSaveStateFlag(true);
|
||||||
|
|
||||||
|
// NB. The following disparity should be resolved:
|
||||||
|
// . A change in h/w via the Configuration property sheets results in a the VM completely restarting (via WM_USER_RESTART)
|
||||||
|
// . A change in h/w via loading a save-state avoids this VM restart
|
||||||
|
// The latter is the desired approach (as the former needs a "power-on" / F2 to start things again)
|
||||||
|
|
||||||
|
sg_PropertySheet.ApplyNewConfig(m_ConfigNew, ConfigOld);
|
||||||
|
|
||||||
|
MemInitializeROM();
|
||||||
|
MemInitializeCustomF8ROM();
|
||||||
|
MemInitializeIO();
|
||||||
|
|
||||||
|
MemUpdatePaging(TRUE);
|
||||||
|
|
||||||
|
// g_Apple2Type may've changed: so redraw frame (title, buttons, leds, etc)
|
||||||
|
SetCharsetType();
|
||||||
|
VideoReinitialize(); // g_CharsetType changed
|
||||||
|
FrameUpdateApple2Type();
|
||||||
|
}
|
||||||
|
catch(std::string szMessage)
|
||||||
|
{
|
||||||
|
MessageBox( g_hFrameWindow,
|
||||||
|
szMessage.c_str(),
|
||||||
|
TEXT("Load State"),
|
||||||
|
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
||||||
|
|
||||||
|
PostMessage(g_hFrameWindow, WM_USER_RESTART, 0, 0); // Power-cycle VM (undoing all the new state just loaded)
|
||||||
|
}
|
||||||
|
|
||||||
|
yamlHelper.FinaliseParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snapshot_LoadState()
|
||||||
|
{
|
||||||
|
const std::string ext_aws = (".aws");
|
||||||
|
const size_t pos = g_strSaveStatePathname.size() - ext_aws.size();
|
||||||
|
if (g_strSaveStatePathname.find(ext_aws, pos) != std::string::npos) // find ".aws" at end of pathname
|
||||||
|
{
|
||||||
|
Snapshot_LoadState_v1();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Snapshot_LoadState_v2();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// todo:
|
||||||
|
// . Uthernet card
|
||||||
|
|
||||||
|
void Snapshot_SaveState(void)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
YamlSaveHelper yamlSaveHelper(g_strSaveStatePathname);
|
||||||
|
yamlSaveHelper.FileHdr(SS_FILE_VER);
|
||||||
|
|
||||||
|
// Unit: Apple2
|
||||||
|
{
|
||||||
|
yamlSaveHelper.UnitHdr(GetSnapshotUnitApple2Name(), UNIT_APPLE2_VER);
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
|
yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_MODEL, GetApple2TypeAsString().c_str());
|
||||||
|
CpuSaveSnapshot(yamlSaveHelper);
|
||||||
|
JoySaveSnapshot(yamlSaveHelper);
|
||||||
|
KeybSaveSnapshot(yamlSaveHelper);
|
||||||
|
SpkrSaveSnapshot(yamlSaveHelper);
|
||||||
|
VideoSaveSnapshot(yamlSaveHelper);
|
||||||
|
MemSaveSnapshot(yamlSaveHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unit: Aux slot
|
||||||
|
MemSaveSnapshotAux(yamlSaveHelper);
|
||||||
|
|
||||||
|
// Unit: Slots
|
||||||
|
{
|
||||||
|
yamlSaveHelper.UnitHdr(GetSnapshotUnitSlotsName(), UNIT_SLOTS_VER);
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
|
Printer_SaveSnapshot(yamlSaveHelper);
|
||||||
|
|
||||||
|
sg_SSC.SaveSnapshot(yamlSaveHelper);
|
||||||
|
|
||||||
|
sg_Mouse.SaveSnapshot(yamlSaveHelper);
|
||||||
|
|
||||||
|
if (g_Slot4 == CT_Z80)
|
||||||
|
Z80_SaveSnapshot(yamlSaveHelper, 4);
|
||||||
|
|
||||||
|
if (g_Slot5 == CT_Z80)
|
||||||
|
Z80_SaveSnapshot(yamlSaveHelper, 5);
|
||||||
|
|
||||||
|
if (g_Slot4 == CT_MockingboardC)
|
||||||
|
MB_SaveSnapshot(yamlSaveHelper, 4);
|
||||||
|
|
||||||
|
if (g_Slot5 == CT_MockingboardC)
|
||||||
|
MB_SaveSnapshot(yamlSaveHelper, 5);
|
||||||
|
|
||||||
|
if (g_Slot4 == CT_Phasor)
|
||||||
|
Phasor_SaveSnapshot(yamlSaveHelper, 4);
|
||||||
|
|
||||||
|
DiskSaveSnapshot(yamlSaveHelper);
|
||||||
|
|
||||||
|
HD_SaveSnapshot(yamlSaveHelper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(std::string szMessage)
|
||||||
|
{
|
||||||
|
MessageBox( g_hFrameWindow,
|
||||||
|
szMessage.c_str(),
|
||||||
|
TEXT("Save State"),
|
||||||
|
MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
136
source/SaveState_Structs_common.h
Normal file
136
source/SaveState_Structs_common.h
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Structs used by save-state file
|
||||||
|
|
||||||
|
// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT ***
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define MAKE_VERSION(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | (d))
|
||||||
|
|
||||||
|
#define AW_SS_TAG 'SSWA' // 'AWSS' = AppleWin SnapShot
|
||||||
|
|
||||||
|
struct SS_FILE_HDR
|
||||||
|
{
|
||||||
|
DWORD dwTag; // "AWSS"
|
||||||
|
DWORD dwVersion;
|
||||||
|
DWORD dwChecksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SS_UNIT_HDR
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
DWORD dwLength; // Byte length of this unit struct
|
||||||
|
DWORD dwVersion;
|
||||||
|
} v1;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
DWORD Length; // Byte length of this unit struct
|
||||||
|
WORD Type; // SS_UNIT_TYPE
|
||||||
|
WORD Version; // Incrementing value from 1
|
||||||
|
} v2;
|
||||||
|
} hdr;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SS_UNIT_TYPE
|
||||||
|
{
|
||||||
|
UT_Reserved = 0,
|
||||||
|
UT_Apple2,
|
||||||
|
UT_Card,
|
||||||
|
UT_Config,
|
||||||
|
};
|
||||||
|
|
||||||
|
const UINT nMemMainSize = 64*1024;
|
||||||
|
const UINT nMemAuxSize = 64*1024;
|
||||||
|
|
||||||
|
const UINT kSLOT_LANG = 0;
|
||||||
|
const UINT kSLOT_AUX = 8;
|
||||||
|
|
||||||
|
struct SS_CARD_HDR
|
||||||
|
{
|
||||||
|
SS_UNIT_HDR UnitHdr;
|
||||||
|
DWORD Type; // SS_CARDTYPE
|
||||||
|
DWORD Slot; // [1..7], 0=Language card, 8=Aux
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SS_CARDTYPE
|
||||||
|
{
|
||||||
|
CT_Empty = 0,
|
||||||
|
CT_Disk2, // Apple Disk][
|
||||||
|
CT_SSC, // Apple Super Serial Card
|
||||||
|
CT_MockingboardC, // Soundcard
|
||||||
|
CT_GenericPrinter,
|
||||||
|
CT_GenericHDD, // Hard disk
|
||||||
|
CT_GenericClock,
|
||||||
|
CT_MouseInterface,
|
||||||
|
CT_Z80,
|
||||||
|
CT_Phasor, // Soundcard
|
||||||
|
CT_Echo, // Soundcard
|
||||||
|
CT_SAM, // Soundcard: Software Automated Mouth
|
||||||
|
CT_80Col, // 80 column card (no memory)
|
||||||
|
CT_Extended80Col, // Extended 80-col card (64K)
|
||||||
|
CT_RamWorksIII, // RamWorksIII (up to 8MB)
|
||||||
|
CT_Uthernet,
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct SS_CARD_EMPTY
|
||||||
|
{
|
||||||
|
SS_CARD_HDR Hdr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct IWORD
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
BYTE l;
|
||||||
|
BYTE h;
|
||||||
|
};
|
||||||
|
USHORT w;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SY6522
|
||||||
|
{
|
||||||
|
BYTE ORB; // $00 - Port B
|
||||||
|
BYTE ORA; // $01 - Port A (with handshaking)
|
||||||
|
BYTE DDRB; // $02 - Data Direction Register B
|
||||||
|
BYTE DDRA; // $03 - Data Direction Register A
|
||||||
|
//
|
||||||
|
// $04 - Read counter (L) / Write latch (L)
|
||||||
|
// $05 - Read / Write & initiate count (H)
|
||||||
|
// $06 - Read / Write & latch (L)
|
||||||
|
// $07 - Read / Write & latch (H)
|
||||||
|
// $08 - Read counter (L) / Write latch (L)
|
||||||
|
// $09 - Read counter (H) / Write latch (H)
|
||||||
|
IWORD TIMER1_COUNTER;
|
||||||
|
IWORD TIMER1_LATCH;
|
||||||
|
IWORD TIMER2_COUNTER;
|
||||||
|
IWORD TIMER2_LATCH;
|
||||||
|
//
|
||||||
|
BYTE SERIAL_SHIFT; // $0A
|
||||||
|
BYTE ACR; // $0B - Auxiliary Control Register
|
||||||
|
BYTE PCR; // $0C - Peripheral Control Register
|
||||||
|
BYTE IFR; // $0D - Interrupt Flag Register
|
||||||
|
BYTE IER; // $0E - Interrupt Enable Register
|
||||||
|
BYTE ORA_NO_HS; // $0F - Port A (without handshaking)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SSI263A
|
||||||
|
{
|
||||||
|
BYTE DurationPhoneme;
|
||||||
|
BYTE Inflection; // I10..I3
|
||||||
|
BYTE RateInflection;
|
||||||
|
BYTE CtrlArtAmp;
|
||||||
|
BYTE FilterFreq;
|
||||||
|
//
|
||||||
|
BYTE CurrentMode; // b7:6=Mode; b0=D7 pin (for IRQ)
|
||||||
|
};
|
147
source/SaveState_Structs_v1.h
Normal file
147
source/SaveState_Structs_v1.h
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DiskDefs.h"
|
||||||
|
#include "SaveState_Structs_common.h"
|
||||||
|
|
||||||
|
// Structs used by save-state file v1
|
||||||
|
|
||||||
|
// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT ***
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct SS_CPU6502
|
||||||
|
{
|
||||||
|
BYTE A;
|
||||||
|
BYTE X;
|
||||||
|
BYTE Y;
|
||||||
|
BYTE P;
|
||||||
|
BYTE S;
|
||||||
|
USHORT PC;
|
||||||
|
unsigned __int64 nCumulativeCycles;
|
||||||
|
// IRQ = OR-sum of all interrupt sources
|
||||||
|
};
|
||||||
|
|
||||||
|
const UINT uRecvBufferSize = 9;
|
||||||
|
|
||||||
|
struct SS_IO_Comms
|
||||||
|
{
|
||||||
|
DWORD baudrate;
|
||||||
|
BYTE bytesize;
|
||||||
|
BYTE commandbyte;
|
||||||
|
DWORD comminactivity; // If non-zero then COM port open
|
||||||
|
BYTE controlbyte;
|
||||||
|
BYTE parity;
|
||||||
|
BYTE recvbuffer[uRecvBufferSize];
|
||||||
|
DWORD recvbytes;
|
||||||
|
BYTE stopbits;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SS_IO_Joystick
|
||||||
|
{
|
||||||
|
unsigned __int64 nJoyCntrResetCycle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SS_IO_Keyboard
|
||||||
|
{
|
||||||
|
DWORD keyboardqueries;
|
||||||
|
BYTE nLastKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SS_IO_Speaker
|
||||||
|
{
|
||||||
|
unsigned __int64 nSpkrLastCycle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SS_IO_Video
|
||||||
|
{
|
||||||
|
bool bAltCharSet; // charoffs
|
||||||
|
DWORD dwVidMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SS_BaseMemory
|
||||||
|
{
|
||||||
|
DWORD dwMemMode;
|
||||||
|
BOOL bLastWriteRam;
|
||||||
|
BYTE nMemMain[nMemMainSize];
|
||||||
|
BYTE nMemAux[nMemAuxSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SS_APPLE2_Unit
|
||||||
|
{
|
||||||
|
SS_UNIT_HDR UnitHdr;
|
||||||
|
SS_CPU6502 CPU6502;
|
||||||
|
SS_IO_Comms Comms;
|
||||||
|
SS_IO_Joystick Joystick;
|
||||||
|
SS_IO_Keyboard Keyboard;
|
||||||
|
SS_IO_Speaker Speaker;
|
||||||
|
SS_IO_Video Video;
|
||||||
|
SS_BaseMemory Memory;
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct DISK2_Unit
|
||||||
|
{
|
||||||
|
char szFileName[MAX_PATH];
|
||||||
|
int track;
|
||||||
|
int phase;
|
||||||
|
int byte;
|
||||||
|
BOOL writeprotected;
|
||||||
|
BOOL trackimagedata;
|
||||||
|
BOOL trackimagedirty;
|
||||||
|
DWORD spinning;
|
||||||
|
DWORD writelight;
|
||||||
|
int nibbles;
|
||||||
|
BYTE nTrack[NIBBLES_PER_TRACK];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SS_CARD_DISK2
|
||||||
|
{
|
||||||
|
SS_CARD_HDR Hdr;
|
||||||
|
DISK2_Unit Unit[2];
|
||||||
|
WORD phases;
|
||||||
|
WORD currdrive;
|
||||||
|
BOOL diskaccessed;
|
||||||
|
BOOL enhancedisk;
|
||||||
|
BYTE floppylatch;
|
||||||
|
BOOL floppymotoron;
|
||||||
|
BOOL floppywritemode;
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct MB_Unit_v1
|
||||||
|
{
|
||||||
|
SY6522 RegsSY6522;
|
||||||
|
BYTE RegsAY8910[16];
|
||||||
|
SSI263A RegsSSI263;
|
||||||
|
BYTE nAYCurrentRegister;
|
||||||
|
bool bTimer1IrqPending;
|
||||||
|
bool bTimer2IrqPending;
|
||||||
|
bool bSpeechIrqPending;
|
||||||
|
};
|
||||||
|
|
||||||
|
const UINT MB_UNITS_PER_CARD_v1 = 2;
|
||||||
|
|
||||||
|
struct SS_CARD_MOCKINGBOARD_v1
|
||||||
|
{
|
||||||
|
SS_CARD_HDR Hdr;
|
||||||
|
MB_Unit_v1 Unit[MB_UNITS_PER_CARD_v1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct APPLEWIN_SNAPSHOT_v1
|
||||||
|
{
|
||||||
|
SS_FILE_HDR Hdr;
|
||||||
|
SS_APPLE2_Unit Apple2Unit;
|
||||||
|
SS_CARD_EMPTY Empty1; // Slot1
|
||||||
|
SS_CARD_EMPTY Empty2; // Slot2
|
||||||
|
SS_CARD_EMPTY Empty3; // Slot3
|
||||||
|
SS_CARD_MOCKINGBOARD_v1 Mockingboard1; // Slot4
|
||||||
|
SS_CARD_MOCKINGBOARD_v1 Mockingboard2; // Slot5
|
||||||
|
SS_CARD_DISK2 Disk2; // Slot6
|
||||||
|
SS_CARD_EMPTY Empty7; // Slot7
|
||||||
|
};
|
||||||
|
|
||||||
|
const UINT kSnapshotSize_v1 = 145400; // Const size for v1
|
|
@ -46,6 +46,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "SerialComms.h"
|
#include "SerialComms.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#include "..\resource\resource.h"
|
#include "..\resource\resource.h"
|
||||||
|
|
||||||
|
@ -72,7 +73,8 @@ SSC_DIPSW CSuperSerialCard::m_DIPSWDefault =
|
||||||
|
|
||||||
CSuperSerialCard::CSuperSerialCard() :
|
CSuperSerialCard::CSuperSerialCard() :
|
||||||
m_aySerialPortChoices(NULL),
|
m_aySerialPortChoices(NULL),
|
||||||
m_uTCPChoiceItemIdx(0)
|
m_uTCPChoiceItemIdx(0),
|
||||||
|
m_uSlot(0)
|
||||||
{
|
{
|
||||||
memset(m_ayCurrentSerialPortName, 0, sizeof(m_ayCurrentSerialPortName));
|
memset(m_ayCurrentSerialPortName, 0, sizeof(m_ayCurrentSerialPortName));
|
||||||
m_dwSerialPortItem = 0;
|
m_dwSerialPortItem = 0;
|
||||||
|
@ -831,6 +833,8 @@ void CSuperSerialCard::CommInitialize(LPBYTE pCxRomPeripheral, UINT uSlot)
|
||||||
|
|
||||||
memcpy(pCxRomPeripheral + uSlot*256, pData+SSC_SLOT_FW_OFFSET, SSC_SLOT_FW_SIZE);
|
memcpy(pCxRomPeripheral + uSlot*256, pData+SSC_SLOT_FW_OFFSET, SSC_SLOT_FW_SIZE);
|
||||||
|
|
||||||
|
m_uSlot = uSlot;
|
||||||
|
|
||||||
// Expansion ROM
|
// Expansion ROM
|
||||||
if (m_pExpansionRom == NULL)
|
if (m_pExpansionRom == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1045,7 +1049,7 @@ DWORD WINAPI CSuperSerialCard::CommThread(LPVOID lpParameter)
|
||||||
sprintf(szDbg, "CommThread: Err=Other (0x%08X): InQueue=0x%08X, OutQueue=0x%08X\n", dwErrors, Stat.cbInQue, Stat.cbOutQue);
|
sprintf(szDbg, "CommThread: Err=Other (0x%08X): InQueue=0x%08X, OutQueue=0x%08X\n", dwErrors, Stat.cbInQue, Stat.cbOutQue);
|
||||||
OutputDebugString(szDbg);
|
OutputDebugString(szDbg);
|
||||||
if (g_fh)
|
if (g_fh)
|
||||||
fprintf(g_fh, szDbg);
|
fprintf(g_fh, "%s", szDbg);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1293,30 +1297,131 @@ void CSuperSerialCard::SetSerialPortName(const char* pSerialPortName)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD CSuperSerialCard::CommGetSnapshot(SS_IO_Comms* pSS)
|
void CSuperSerialCard::SetSnapshot_v1( const DWORD baudrate,
|
||||||
|
const BYTE bytesize,
|
||||||
|
const BYTE commandbyte,
|
||||||
|
const DWORD comminactivity,
|
||||||
|
const BYTE controlbyte,
|
||||||
|
const BYTE parity,
|
||||||
|
const BYTE stopbits)
|
||||||
{
|
{
|
||||||
pSS->baudrate = m_uBaudRate;
|
m_uBaudRate = baudrate;
|
||||||
pSS->bytesize = m_uByteSize;
|
m_uByteSize = bytesize;
|
||||||
pSS->commandbyte = m_uCommandByte;
|
m_uCommandByte = commandbyte;
|
||||||
pSS->comminactivity = m_dwCommInactivity;
|
m_dwCommInactivity = comminactivity;
|
||||||
pSS->controlbyte = m_uControlByte;
|
m_uControlByte = controlbyte;
|
||||||
pSS->parity = m_uParity;
|
m_uParity = parity;
|
||||||
// memcpy(pSS->recvbuffer, m_RecvBuffer, uRecvBufferSize);
|
// memcpy(m_RecvBuffer, pSS->recvbuffer, uRecvBufferSize);
|
||||||
pSS->recvbytes = 0;
|
// m_vRecvBytes = recvbytes;
|
||||||
pSS->stopbits = m_uStopBits;
|
m_uStopBits = stopbits;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD CSuperSerialCard::CommSetSnapshot(SS_IO_Comms* pSS)
|
//===========================================================================
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_CARD_SSC "Super Serial Card"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_DIPSWDEFAULT "DIPSW Default"
|
||||||
|
#define SS_YAML_KEY_DIPSWCURRENT "DIPSW Current"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_BAUDRATE "Baud Rate"
|
||||||
|
#define SS_YAML_KEY_FWMODE "Firmware mode"
|
||||||
|
#define SS_YAML_KEY_STOPBITS "Stop Bits"
|
||||||
|
#define SS_YAML_KEY_BYTESIZE "Byte Size"
|
||||||
|
#define SS_YAML_KEY_PARITY "Parity"
|
||||||
|
#define SS_YAML_KEY_LINEFEED "Linefeed"
|
||||||
|
#define SS_YAML_KEY_INTERRUPTS "Interrupts"
|
||||||
|
#define SS_YAML_KEY_CONTROL "Control Byte"
|
||||||
|
#define SS_YAML_KEY_COMMAND "Command Byte"
|
||||||
|
#define SS_YAML_KEY_INACTIVITY "Comm Inactivity"
|
||||||
|
#define SS_YAML_KEY_TXIRQENABLED "TX IRQ Enabled"
|
||||||
|
#define SS_YAML_KEY_RXIRQENABLED "RX IRQ Enabled"
|
||||||
|
#define SS_YAML_KEY_TXIRQPENDING "TX IRQ Pending"
|
||||||
|
#define SS_YAML_KEY_RXIRQPENDING "RX IRQ Pending"
|
||||||
|
#define SS_YAML_KEY_WRITTENTX "Written TX"
|
||||||
|
#define SS_YAML_KEY_SERIALPORTNAME "Serial Port Name"
|
||||||
|
|
||||||
|
std::string CSuperSerialCard::GetSnapshotCardName(void)
|
||||||
{
|
{
|
||||||
m_uBaudRate = pSS->baudrate;
|
static const std::string name(SS_YAML_VALUE_CARD_SSC);
|
||||||
m_uByteSize = pSS->bytesize;
|
return name;
|
||||||
m_uCommandByte = pSS->commandbyte;
|
}
|
||||||
m_dwCommInactivity = pSS->comminactivity;
|
|
||||||
m_uControlByte = pSS->controlbyte;
|
void CSuperSerialCard::SaveSnapshotDIPSW(YamlSaveHelper& yamlSaveHelper, std::string key, SSC_DIPSW& dipsw)
|
||||||
m_uParity = pSS->parity;
|
{
|
||||||
// memcpy(m_RecvBuffer, pSS->recvbuffer, uRecvBufferSize);
|
YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", key.c_str());
|
||||||
// m_vRecvBytes = pSS->recvbytes;
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_BAUDRATE, dipsw.uBaudRate);
|
||||||
m_uStopBits = pSS->stopbits;
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_FWMODE, dipsw.eFirmwareMode);
|
||||||
return 0;
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_STOPBITS, dipsw.uStopBits);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_BYTESIZE, dipsw.uByteSize);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_PARITY, dipsw.uParity);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_LINEFEED, dipsw.bLinefeed);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_INTERRUPTS, dipsw.bInterrupts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSuperSerialCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Slot slot(yamlSaveHelper, GetSnapshotCardName(), m_uSlot, 1);
|
||||||
|
|
||||||
|
YamlSaveHelper::Label unit(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
SaveSnapshotDIPSW(yamlSaveHelper, SS_YAML_KEY_DIPSWDEFAULT, m_DIPSWDefault);
|
||||||
|
SaveSnapshotDIPSW(yamlSaveHelper, SS_YAML_KEY_DIPSWCURRENT, m_DIPSWCurrent);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_BAUDRATE, m_uBaudRate);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_STOPBITS, m_uStopBits);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_BYTESIZE, m_uByteSize);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_PARITY, m_uParity);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_CONTROL, m_uControlByte);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_COMMAND, m_uCommandByte);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_INACTIVITY, m_dwCommInactivity);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_TXIRQENABLED, m_bTxIrqEnabled);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_RXIRQENABLED, m_bRxIrqEnabled);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_TXIRQPENDING, m_vbTxIrqPending);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_RXIRQPENDING, m_vbRxIrqPending);
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_WRITTENTX, m_bWrittenTx);
|
||||||
|
yamlSaveHelper.SaveString(SS_YAML_KEY_SERIALPORTNAME, GetSerialPortName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSuperSerialCard::LoadSnapshotDIPSW(YamlLoadHelper& yamlLoadHelper, std::string key, SSC_DIPSW& dipsw)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(key))
|
||||||
|
throw std::string("Card: Expected key: " + key);
|
||||||
|
|
||||||
|
dipsw.uBaudRate = yamlLoadHelper.LoadUint(SS_YAML_KEY_BAUDRATE);
|
||||||
|
dipsw.eFirmwareMode = (eFWMODE) yamlLoadHelper.LoadUint(SS_YAML_KEY_FWMODE);
|
||||||
|
dipsw.uStopBits = yamlLoadHelper.LoadUint(SS_YAML_KEY_STOPBITS);
|
||||||
|
dipsw.uByteSize = yamlLoadHelper.LoadUint(SS_YAML_KEY_BYTESIZE);
|
||||||
|
dipsw.uParity = yamlLoadHelper.LoadUint(SS_YAML_KEY_PARITY);
|
||||||
|
dipsw.bLinefeed = yamlLoadHelper.LoadBool(SS_YAML_KEY_LINEFEED);
|
||||||
|
dipsw.bInterrupts = yamlLoadHelper.LoadBool(SS_YAML_KEY_INTERRUPTS);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSuperSerialCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||||
|
{
|
||||||
|
if (slot != 2) // fixme
|
||||||
|
throw std::string("Card: wrong slot");
|
||||||
|
|
||||||
|
if (version != 1)
|
||||||
|
throw std::string("Card: wrong version");
|
||||||
|
|
||||||
|
LoadSnapshotDIPSW(yamlLoadHelper, SS_YAML_KEY_DIPSWDEFAULT, m_DIPSWDefault);
|
||||||
|
LoadSnapshotDIPSW(yamlLoadHelper, SS_YAML_KEY_DIPSWCURRENT, m_DIPSWCurrent);
|
||||||
|
|
||||||
|
m_uBaudRate = yamlLoadHelper.LoadUint(SS_YAML_KEY_BAUDRATE);
|
||||||
|
m_uStopBits = yamlLoadHelper.LoadUint(SS_YAML_KEY_STOPBITS);
|
||||||
|
m_uByteSize = yamlLoadHelper.LoadUint(SS_YAML_KEY_BYTESIZE);
|
||||||
|
m_uParity = yamlLoadHelper.LoadUint(SS_YAML_KEY_PARITY);
|
||||||
|
m_uControlByte = yamlLoadHelper.LoadUint(SS_YAML_KEY_CONTROL);
|
||||||
|
m_uCommandByte = yamlLoadHelper.LoadUint(SS_YAML_KEY_COMMAND);
|
||||||
|
m_dwCommInactivity = yamlLoadHelper.LoadUint(SS_YAML_KEY_INACTIVITY);
|
||||||
|
m_bTxIrqEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_TXIRQENABLED);
|
||||||
|
m_bRxIrqEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_RXIRQENABLED);
|
||||||
|
m_vbTxIrqPending = yamlLoadHelper.LoadBool(SS_YAML_KEY_TXIRQPENDING);
|
||||||
|
m_vbRxIrqPending = yamlLoadHelper.LoadBool(SS_YAML_KEY_RXIRQPENDING);
|
||||||
|
m_bWrittenTx = yamlLoadHelper.LoadBool(SS_YAML_KEY_WRITTENTX);
|
||||||
|
|
||||||
|
std::string serialPortName = yamlLoadHelper.LoadString(SS_YAML_KEY_SERIALPORTNAME);
|
||||||
|
SetSerialPortName(serialPortName.c_str());
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,10 @@ public:
|
||||||
void CommDestroy();
|
void CommDestroy();
|
||||||
void CommSetSerialPort(HWND hWindow, DWORD dwNewSerialPortItem);
|
void CommSetSerialPort(HWND hWindow, DWORD dwNewSerialPortItem);
|
||||||
void CommUpdate(DWORD);
|
void CommUpdate(DWORD);
|
||||||
DWORD CommGetSnapshot(SS_IO_Comms* pSS);
|
void SetSnapshot_v1(const DWORD baudrate, const BYTE bytesize, const BYTE commandbyte, const DWORD comminactivity, const BYTE controlbyte, const BYTE parity, const BYTE stopbits);
|
||||||
DWORD CommSetSnapshot(SS_IO_Comms* pSS);
|
std::string GetSnapshotCardName(void);
|
||||||
|
void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||||
|
|
||||||
char* GetSerialPortChoices();
|
char* GetSerialPortChoices();
|
||||||
DWORD GetSerialPort() { return m_dwSerialPortItem; } // Drop-down list item
|
DWORD GetSerialPort() { return m_dwSerialPortItem; } // Drop-down list item
|
||||||
|
@ -72,6 +74,8 @@ private:
|
||||||
void CommThUninit();
|
void CommThUninit();
|
||||||
UINT GetNumSerialPortChoices() { return m_vecSerialPortsItems.size(); }
|
UINT GetNumSerialPortChoices() { return m_vecSerialPortsItems.size(); }
|
||||||
void ScanCOMPorts();
|
void ScanCOMPorts();
|
||||||
|
void SaveSnapshotDIPSW(class YamlSaveHelper& yamlSaveHelper, std::string key, SSC_DIPSW& dipsw);
|
||||||
|
void LoadSnapshotDIPSW(class YamlLoadHelper& yamlLoadHelper, std::string key, SSC_DIPSW& dipsw);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -134,4 +138,5 @@ private:
|
||||||
OVERLAPPED m_o;
|
OVERLAPPED m_o;
|
||||||
|
|
||||||
BYTE* m_pExpansionRom;
|
BYTE* m_pExpansionRom;
|
||||||
|
UINT m_uSlot;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "SoundCore.h"
|
#include "SoundCore.h"
|
||||||
#include "Speaker.h"
|
#include "Speaker.h"
|
||||||
#include "Video.h" // VideoRedrawScreen()
|
#include "Video.h" // VideoRedrawScreen()
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#include "Debugger\Debug.h" // For DWORD extbench
|
#include "Debugger\Debug.h" // For DWORD extbench
|
||||||
|
|
||||||
|
@ -51,11 +52,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
// their buffers are running low.
|
// their buffers are running low.
|
||||||
//
|
//
|
||||||
|
|
||||||
#define SOUND_NONE 0
|
|
||||||
#define SOUND_DIRECT 1
|
|
||||||
#define SOUND_SMART 2
|
|
||||||
#define SOUND_WAVE 3
|
|
||||||
|
|
||||||
static const unsigned short g_nSPKR_NumChannels = 1;
|
static const unsigned short g_nSPKR_NumChannels = 1;
|
||||||
static const DWORD g_dwDSSpkrBufferSize = MAX_SAMPLES * sizeof(short) * g_nSPKR_NumChannels;
|
static const DWORD g_dwDSSpkrBufferSize = MAX_SAMPLES * sizeof(short) * g_nSPKR_NumChannels;
|
||||||
|
|
||||||
|
@ -66,18 +62,20 @@ static short* g_pSpeakerBuffer = NULL;
|
||||||
// Globals (SOUND_WAVE)
|
// Globals (SOUND_WAVE)
|
||||||
const short SPKR_DATA_INIT = (short)0x8000;
|
const short SPKR_DATA_INIT = (short)0x8000;
|
||||||
|
|
||||||
static short g_nSpeakerData = SPKR_DATA_INIT;
|
short g_nSpeakerData = SPKR_DATA_INIT;
|
||||||
static UINT g_nBufferIdx = 0;
|
static UINT g_nBufferIdx = 0;
|
||||||
|
|
||||||
static short* g_pRemainderBuffer = NULL;
|
static short* g_pRemainderBuffer = NULL;
|
||||||
static UINT g_nRemainderBufferSize; // Setup in SpkrInitialize()
|
static UINT g_nRemainderBufferSize; // Setup in SpkrInitialize()
|
||||||
static UINT g_nRemainderBufferIdx; // Setup in SpkrInitialize()
|
static UINT g_nRemainderBufferIdx; // Setup in SpkrInitialize()
|
||||||
|
|
||||||
|
|
||||||
// Application-wide globals:
|
// Application-wide globals:
|
||||||
DWORD soundtype = SOUND_WAVE;
|
DWORD soundtype = SOUND_WAVE;
|
||||||
double g_fClksPerSpkrSample; // Setup in SetClksPerSpkrSample()
|
double g_fClksPerSpkrSample; // Setup in SetClksPerSpkrSample()
|
||||||
|
|
||||||
|
// Allow temporary quietening of speaker (8 bit DAC)
|
||||||
|
bool g_bQuieterSpeaker = false;
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
static DWORD lastcyclenum = 0;
|
static DWORD lastcyclenum = 0;
|
||||||
static DWORD toggles = 0;
|
static DWORD toggles = 0;
|
||||||
|
@ -226,7 +224,7 @@ void SpkrDestroy ()
|
||||||
g_pSpeakerBuffer = NULL;
|
g_pSpeakerBuffer = NULL;
|
||||||
g_pRemainderBuffer = NULL;
|
g_pRemainderBuffer = NULL;
|
||||||
}
|
}
|
||||||
else
|
else if (soundtype == SOUND_DIRECT || soundtype == SOUND_SMART)
|
||||||
{
|
{
|
||||||
InternalBeep(0,0);
|
InternalBeep(0,0);
|
||||||
}
|
}
|
||||||
|
@ -328,8 +326,8 @@ void SpkrReset()
|
||||||
|
|
||||||
BOOL SpkrSetEmulationType (HWND window, DWORD newtype)
|
BOOL SpkrSetEmulationType (HWND window, DWORD newtype)
|
||||||
{
|
{
|
||||||
if (soundtype != SOUND_NONE)
|
SpkrDestroy(); // GH#295: Destroy for all types (even SOUND_NONE)
|
||||||
SpkrDestroy();
|
|
||||||
soundtype = newtype;
|
soundtype = newtype;
|
||||||
if (soundtype != SOUND_NONE)
|
if (soundtype != SOUND_NONE)
|
||||||
SpkrInitialize();
|
SpkrInitialize();
|
||||||
|
@ -447,7 +445,21 @@ BYTE __stdcall SpkrToggle (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
|
||||||
|
|
||||||
UpdateSpkr();
|
UpdateSpkr();
|
||||||
|
|
||||||
|
if (g_bQuieterSpeaker)
|
||||||
|
{
|
||||||
|
// quieten the speaker if 8 bit DAC in use
|
||||||
|
if (g_nSpeakerData == (SPKR_DATA_INIT >> 2))
|
||||||
g_nSpeakerData = ~g_nSpeakerData;
|
g_nSpeakerData = ~g_nSpeakerData;
|
||||||
|
else
|
||||||
|
g_nSpeakerData = SPKR_DATA_INIT>>2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (g_nSpeakerData == SPKR_DATA_INIT)
|
||||||
|
g_nSpeakerData = ~g_nSpeakerData;
|
||||||
|
else
|
||||||
|
g_nSpeakerData = SPKR_DATA_INIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (soundtype != SOUND_NONE)
|
else if (soundtype != SOUND_NONE)
|
||||||
{
|
{
|
||||||
|
@ -875,7 +887,7 @@ static ULONG Spkr_SubmitWaveBuffer(short* pSpeakerBuffer, ULONG nNumSamples)
|
||||||
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
double fTicksSecs = (double)GetTickCount() / 1000.0;
|
||||||
sprintf(szDbg, "%010.3f: [Submit] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X XXX\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
sprintf(szDbg, "%010.3f: [Submit] PC=%08X, WC=%08X, Diff=%08X, Off=%08X, NS=%08X XXX\n", fTicksSecs, dwCurrentPlayCursor, dwCurrentWriteCursor, dwCurrentWriteCursor-dwCurrentPlayCursor, dwByteOffset, nNumSamples);
|
||||||
OutputDebugString(szDbg);
|
OutputDebugString(szDbg);
|
||||||
if (g_fh) fprintf(g_fh, szDbg);
|
if (g_fh) fprintf(g_fh, "%s", szDbg);
|
||||||
|
|
||||||
dwByteOffset = dwCurrentWriteCursor;
|
dwByteOffset = dwCurrentWriteCursor;
|
||||||
nNumSamplesError = 0;
|
nNumSamplesError = 0;
|
||||||
|
@ -993,6 +1005,7 @@ static void Spkr_SetActive(bool bActive)
|
||||||
// Called by SpkrUpdate() after 0.2s of speaker inactivity
|
// Called by SpkrUpdate() after 0.2s of speaker inactivity
|
||||||
g_bSpkrRecentlyActive = false;
|
g_bSpkrRecentlyActive = false;
|
||||||
SpeakerVoice.bRecentlyActive = false;
|
SpeakerVoice.bRecentlyActive = false;
|
||||||
|
g_bQuieterSpeaker = 0; // undo any muting (for 8 bit DAC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1080,14 +1093,33 @@ void Spkr_DSUninit()
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
DWORD SpkrGetSnapshot(SS_IO_Speaker* pSS)
|
void SpkrSetSnapshot_v1(const unsigned __int64 SpkrLastCycle)
|
||||||
{
|
{
|
||||||
pSS->g_nSpkrLastCycle = g_nSpkrLastCycle;
|
g_nSpkrLastCycle = SpkrLastCycle;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD SpkrSetSnapshot(SS_IO_Speaker* pSS)
|
//
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_LASTCYCLE "Last Cycle"
|
||||||
|
|
||||||
|
static std::string SpkrGetSnapshotStructName(void)
|
||||||
{
|
{
|
||||||
g_nSpkrLastCycle = pSS->g_nSpkrLastCycle;
|
static const std::string name("Speaker");
|
||||||
return 0;
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpkrSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SpkrGetSnapshotStructName().c_str());
|
||||||
|
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_LASTCYCLE, g_nSpkrLastCycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpkrLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(SpkrGetSnapshotStructName()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_nSpkrLastCycle = yamlLoadHelper.LoadUint64(SS_YAML_KEY_LASTCYCLE);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define SOUND_NONE 0
|
||||||
|
#define SOUND_DIRECT 1
|
||||||
|
#define SOUND_SMART 2
|
||||||
|
#define SOUND_WAVE 3
|
||||||
|
|
||||||
extern DWORD soundtype;
|
extern DWORD soundtype;
|
||||||
extern double g_fClksPerSpkrSample;
|
extern double g_fClksPerSpkrSample;
|
||||||
|
extern bool g_bQuieterSpeaker;
|
||||||
|
extern short g_nSpeakerData;
|
||||||
|
|
||||||
void SpkrDestroy ();
|
void SpkrDestroy ();
|
||||||
void SpkrInitialize ();
|
void SpkrInitialize ();
|
||||||
|
@ -19,7 +26,8 @@ void Spkr_Demute();
|
||||||
bool Spkr_IsActive();
|
bool Spkr_IsActive();
|
||||||
bool Spkr_DSInit();
|
bool Spkr_DSInit();
|
||||||
void Spkr_DSUninit();
|
void Spkr_DSUninit();
|
||||||
DWORD SpkrGetSnapshot(SS_IO_Speaker* pSS);
|
void SpkrSetSnapshot_v1(const unsigned __int64 SpkrLastCycle);
|
||||||
DWORD SpkrSetSnapshot(SS_IO_Speaker* pSS);
|
void SpkrSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
void SpkrLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
|
||||||
|
|
||||||
BYTE __stdcall SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
BYTE __stdcall SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft);
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#if _MSC_VER >= 1600 // <stdint.h> supported from VS2010 (cl.exe v16.00)
|
#if _MSC_VER >= 1600 // <stdint.h> supported from VS2010 (cl.exe v16.00)
|
||||||
#include <stdint.h> // cleanup WORD DWORD -> uint16_t uint32_t
|
#include <stdint.h> // cleanup WORD DWORD -> uint16_t uint32_t
|
||||||
|
@ -43,6 +42,8 @@ typedef UINT32 uint32_t;
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <stack>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// SM_CXPADDEDBORDER is not supported on 2000 & XP:
|
// SM_CXPADDEDBORDER is not supported on 2000 & XP:
|
||||||
|
|
285
source/Structs.h
285
source/Structs.h
|
@ -1,285 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "DiskDefs.h"
|
|
||||||
|
|
||||||
// Structs used by save-state file
|
|
||||||
|
|
||||||
// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT ***
|
|
||||||
|
|
||||||
#define MAKE_VERSION(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | (d))
|
|
||||||
|
|
||||||
#define AW_SS_TAG 'SSWA' // 'AWSS' = AppleWin SnapShot
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
DWORD dwTag; // "AWSS"
|
|
||||||
DWORD dwVersion;
|
|
||||||
DWORD dwChecksum;
|
|
||||||
} SS_FILE_HDR;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
DWORD dwLength; // Byte length of this unit struct
|
|
||||||
DWORD dwVersion;
|
|
||||||
} SS_UNIT_HDR;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const UINT nMemMainSize = 64*1024;
|
|
||||||
const UINT nMemAuxSize = 64*1024;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
BYTE A;
|
|
||||||
BYTE X;
|
|
||||||
BYTE Y;
|
|
||||||
BYTE P;
|
|
||||||
BYTE S;
|
|
||||||
USHORT PC;
|
|
||||||
unsigned __int64 g_nCumulativeCycles;
|
|
||||||
// IRQ = OR-sum of all interrupt sources
|
|
||||||
} SS_CPU6502;
|
|
||||||
|
|
||||||
const UINT uRecvBufferSize = 9;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
DWORD baudrate;
|
|
||||||
BYTE bytesize;
|
|
||||||
BYTE commandbyte;
|
|
||||||
DWORD comminactivity; // If non-zero then COM port open
|
|
||||||
BYTE controlbyte;
|
|
||||||
BYTE parity;
|
|
||||||
BYTE recvbuffer[uRecvBufferSize];
|
|
||||||
DWORD recvbytes;
|
|
||||||
BYTE stopbits;
|
|
||||||
} SS_IO_Comms;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned __int64 g_nJoyCntrResetCycle;
|
|
||||||
} SS_IO_Joystick;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
DWORD keyboardqueries;
|
|
||||||
BYTE nLastKey;
|
|
||||||
} SS_IO_Keyboard;
|
|
||||||
|
|
||||||
//typedef struct
|
|
||||||
//{
|
|
||||||
//} SS_IO_Memory;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned __int64 g_nSpkrLastCycle;
|
|
||||||
} SS_IO_Speaker;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
bool bAltCharSet; // charoffs
|
|
||||||
DWORD dwVidMode;
|
|
||||||
} SS_IO_Video;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
DWORD dwMemMode;
|
|
||||||
BOOL bLastWriteRam;
|
|
||||||
BYTE nMemMain[nMemMainSize];
|
|
||||||
BYTE nMemAux[nMemAuxSize];
|
|
||||||
} SS_BaseMemory;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SS_UNIT_HDR UnitHdr;
|
|
||||||
SS_CPU6502 CPU6502;
|
|
||||||
SS_IO_Comms Comms;
|
|
||||||
SS_IO_Joystick Joystick;
|
|
||||||
SS_IO_Keyboard Keyboard;
|
|
||||||
// SS_IO_Memory Memory;
|
|
||||||
SS_IO_Speaker Speaker;
|
|
||||||
SS_IO_Video Video;
|
|
||||||
SS_BaseMemory Memory;
|
|
||||||
} SS_APPLE2_Unit;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
DWORD dwComputerEmulation;
|
|
||||||
bool bCustomSpeed;
|
|
||||||
DWORD dwEmulationSpeed;
|
|
||||||
bool bEnhancedDiskSpeed;
|
|
||||||
DWORD dwJoystickType[2];
|
|
||||||
bool bMockingboardEnabled;
|
|
||||||
DWORD dwMonochromeColor;
|
|
||||||
DWORD dwSerialPort;
|
|
||||||
DWORD dwSoundType; // Sound Emulation
|
|
||||||
DWORD dwVideoType; // Video Emulation
|
|
||||||
} SS_AW_CFG;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char StartingDir[MAX_PATH];
|
|
||||||
DWORD dwWindowXpos;
|
|
||||||
DWORD dwWindowYpos;
|
|
||||||
} SS_AW_PREFS;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SS_UNIT_HDR UnitHdr;
|
|
||||||
DWORD dwAppleWinVersion;
|
|
||||||
SS_AW_PREFS Prefs;
|
|
||||||
SS_AW_CFG Cfg;
|
|
||||||
} SS_APPLEWIN_CONFIG;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SS_UNIT_HDR UnitHdr;
|
|
||||||
DWORD dwType; // SS_CARDTYPE
|
|
||||||
DWORD dwSlot; // [1..7]
|
|
||||||
} SS_CARD_HDR;
|
|
||||||
|
|
||||||
enum SS_CARDTYPE
|
|
||||||
{
|
|
||||||
CT_Empty = 0,
|
|
||||||
CT_Disk2, // Apple Disk][
|
|
||||||
CT_SSC, // Apple Super Serial Card
|
|
||||||
CT_MockingboardC, // Soundcard
|
|
||||||
CT_GenericPrinter,
|
|
||||||
CT_GenericHDD, // Hard disk
|
|
||||||
CT_GenericClock,
|
|
||||||
CT_MouseInterface,
|
|
||||||
CT_Z80,
|
|
||||||
CT_Phasor, // Soundcard
|
|
||||||
CT_Echo, // Soundcard
|
|
||||||
CT_SAM, // Soundcard: Software Automated Mouth
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SS_CARD_HDR Hdr;
|
|
||||||
} SS_CARD_EMPTY;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char szFileName[MAX_PATH];
|
|
||||||
int track;
|
|
||||||
int phase;
|
|
||||||
int byte;
|
|
||||||
BOOL writeprotected;
|
|
||||||
BOOL trackimagedata;
|
|
||||||
BOOL trackimagedirty;
|
|
||||||
DWORD spinning;
|
|
||||||
DWORD writelight;
|
|
||||||
int nibbles;
|
|
||||||
BYTE nTrack[NIBBLES_PER_TRACK];
|
|
||||||
} DISK2_Unit;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SS_CARD_HDR Hdr;
|
|
||||||
DISK2_Unit Unit[2];
|
|
||||||
WORD phases;
|
|
||||||
WORD currdrive;
|
|
||||||
BOOL diskaccessed;
|
|
||||||
BOOL enhancedisk;
|
|
||||||
BYTE floppylatch;
|
|
||||||
BOOL floppymotoron;
|
|
||||||
BOOL floppywritemode;
|
|
||||||
} SS_CARD_DISK2;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
BYTE l;
|
|
||||||
BYTE h;
|
|
||||||
};
|
|
||||||
USHORT w;
|
|
||||||
};
|
|
||||||
} IWORD;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
BYTE ORB; // $00 - Port B
|
|
||||||
BYTE ORA; // $01 - Port A (with handshaking)
|
|
||||||
BYTE DDRB; // $02 - Data Direction Register B
|
|
||||||
BYTE DDRA; // $03 - Data Direction Register A
|
|
||||||
//
|
|
||||||
// $04 - Read counter (L) / Write latch (L)
|
|
||||||
// $05 - Read / Write & initiate count (H)
|
|
||||||
// $06 - Read / Write & latch (L)
|
|
||||||
// $07 - Read / Write & latch (H)
|
|
||||||
// $08 - Read counter (L) / Write latch (L)
|
|
||||||
// $09 - Read counter (H) / Write latch (H)
|
|
||||||
IWORD TIMER1_COUNTER;
|
|
||||||
IWORD TIMER1_LATCH;
|
|
||||||
IWORD TIMER2_COUNTER;
|
|
||||||
IWORD TIMER2_LATCH;
|
|
||||||
//
|
|
||||||
BYTE SERIAL_SHIFT; // $0A
|
|
||||||
BYTE ACR; // $0B - Auxiliary Control Register
|
|
||||||
BYTE PCR; // $0C - Peripheral Control Register
|
|
||||||
BYTE IFR; // $0D - Interrupt Flag Register
|
|
||||||
BYTE IER; // $0E - Interrupt Enable Register
|
|
||||||
BYTE ORA_NO_HS; // $0F - Port A (without handshaking)
|
|
||||||
} SY6522;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
BYTE DurationPhonome;
|
|
||||||
BYTE Inflection; // I10..I3
|
|
||||||
BYTE RateInflection;
|
|
||||||
BYTE CtrlArtAmp;
|
|
||||||
BYTE FilterFreq;
|
|
||||||
//
|
|
||||||
BYTE CurrentMode; // b7:6=Mode; b0=D7 pin (for IRQ)
|
|
||||||
} SSI263A;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SY6522 RegsSY6522;
|
|
||||||
BYTE RegsAY8910[16];
|
|
||||||
SSI263A RegsSSI263;
|
|
||||||
BYTE nAYCurrentRegister;
|
|
||||||
bool bTimer1IrqPending;
|
|
||||||
bool bTimer2IrqPending;
|
|
||||||
bool bSpeechIrqPending;
|
|
||||||
} MB_Unit;
|
|
||||||
|
|
||||||
const UINT MB_UNITS_PER_CARD = 2;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SS_CARD_HDR Hdr;
|
|
||||||
MB_Unit Unit[MB_UNITS_PER_CARD];
|
|
||||||
} SS_CARD_MOCKINGBOARD;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SS_FILE_HDR Hdr;
|
|
||||||
SS_APPLE2_Unit Apple2Unit;
|
|
||||||
// SS_APPLEWIN_CONFIG AppleWinCfg;
|
|
||||||
SS_CARD_EMPTY Empty1; // Slot1
|
|
||||||
SS_CARD_EMPTY Empty2; // Slot2
|
|
||||||
SS_CARD_EMPTY Empty3; // Slot3
|
|
||||||
SS_CARD_MOCKINGBOARD Mockingboard1; // Slot4
|
|
||||||
SS_CARD_MOCKINGBOARD Mockingboard2; // Slot5
|
|
||||||
SS_CARD_DISK2 Disk2; // Slot6
|
|
||||||
SS_CARD_EMPTY Empty7; // Slot7
|
|
||||||
} APPLEWIN_SNAPSHOT;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
|
@ -24,8 +24,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
/* Description: This module is created for emulation of the 8bit character mode (mode 1) switch,
|
/* Description: This module is created for emulation of the 8bit character mode (mode 1) switch,
|
||||||
* which is located in $c060, and so far does not intend to emulate a tape device.
|
* which is located in $c060, and so far does not intend to emulate a tape device.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* Author: Various
|
* Author: Various
|
||||||
|
*
|
||||||
|
* In comments, UTA2E is an abbreviation for a reference to "Understanding the Apple //e" by James Sather
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
@ -33,6 +34,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "AppleWin.h"
|
#include "AppleWin.h"
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
#include "Pravets.h"
|
||||||
|
|
||||||
static bool g_CapsLockAllowed = false;
|
static bool g_CapsLockAllowed = false;
|
||||||
|
|
||||||
|
@ -76,7 +78,7 @@ BYTE __stdcall TapeRead(WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft)
|
||||||
return C060;
|
return C060;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (1<<7) | (MemReadFloatingBus(nCyclesLeft) & 0x7F); // Keep high-bit fixed (since TAPEIN isn't supported)
|
return MemReadFloatingBus(1, nCyclesLeft); // TAPEIN has high bit 1 when input is low or not connected (UTA2E page 7-5, 7-6)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "..\resource\resource.h"
|
#include "..\resource\resource.h"
|
||||||
#include "Configuration\PropertySheet.h"
|
#include "Configuration\PropertySheet.h"
|
||||||
#include "Debugger\Debugger_Color.h" // For NUM_DEBUG_COLORS
|
#include "Debugger\Debugger_Color.h" // For NUM_DEBUG_COLORS
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
#define HALF_PIXEL_SOLID 1
|
#define HALF_PIXEL_SOLID 1
|
||||||
#define HALF_PIXEL_BLEED 0
|
#define HALF_PIXEL_BLEED 0
|
||||||
|
@ -590,7 +591,6 @@ static inline int GetOriginal2EOffset(BYTE ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
#define ROL_NIB(x) ( (((x)<<1)&0xF) | (((x)>>3)&1) )
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ----- ALL GLOBALLY ACCESSIBLE FUNCTIONS ARE BELOW THIS LINE -----
|
// ----- ALL GLOBALLY ACCESSIBLE FUNCTIONS ARE BELOW THIS LINE -----
|
||||||
|
@ -1195,11 +1195,10 @@ void VideoRefreshScreen ( int bVideoModeFlags )
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void VideoReinitialize ()
|
void VideoReinitialize ()
|
||||||
{
|
{
|
||||||
NTSC_VideoInitAppleType();
|
NTSC_VideoInitAppleType(g_dwCyclesThisFrame);
|
||||||
NTSC_SetVideoStyle();
|
NTSC_SetVideoStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void VideoResetState ()
|
void VideoResetState ()
|
||||||
{
|
{
|
||||||
|
@ -1220,8 +1219,8 @@ BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
|
||||||
|
|
||||||
switch (address)
|
switch (address)
|
||||||
{
|
{
|
||||||
case 0x00: g_uVideoMode &= ~VF_80STORE; ; break;
|
case 0x00: g_uVideoMode &= ~VF_80STORE; break;
|
||||||
case 0x01: g_uVideoMode |= VF_80STORE; ; break;
|
case 0x01: g_uVideoMode |= VF_80STORE; break;
|
||||||
case 0x0C: if (!IS_APPLE2){g_uVideoMode &= ~VF_80COL; NTSC_SetVideoTextMode(40);}; break;
|
case 0x0C: if (!IS_APPLE2){g_uVideoMode &= ~VF_80COL; NTSC_SetVideoTextMode(40);}; break;
|
||||||
case 0x0D: if (!IS_APPLE2){g_uVideoMode |= VF_80COL; NTSC_SetVideoTextMode(80);}; break;
|
case 0x0D: if (!IS_APPLE2){g_uVideoMode |= VF_80COL; NTSC_SetVideoTextMode(80);}; break;
|
||||||
case 0x0E: if (!IS_APPLE2) g_nAltCharSetOffset = 0; break; // Alternate char set off
|
case 0x0E: if (!IS_APPLE2) g_nAltCharSetOffset = 0; break; // Alternate char set off
|
||||||
|
@ -1238,7 +1237,7 @@ BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
|
||||||
case 0x5F: if (!IS_APPLE2) g_uVideoMode &= ~VF_DHIRES; break;
|
case 0x5F: if (!IS_APPLE2) g_uVideoMode &= ~VF_DHIRES; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apple IIe, Techical Nodtes, #3: Double High-Resolution Graphics
|
// Apple IIe, Techical Notes, #3: Double High-Resolution Graphics
|
||||||
// 80STORE must be OFF to display page 2
|
// 80STORE must be OFF to display page 2
|
||||||
if (SW_80STORE)
|
if (SW_80STORE)
|
||||||
g_uVideoMode &= ~VF_PAGE2;
|
g_uVideoMode &= ~VF_PAGE2;
|
||||||
|
@ -1260,7 +1259,7 @@ BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
|
||||||
// NB. Deferring the update by just setting /g_VideoForceFullRedraw/ is not an option, since this doesn't provide "flip-immediate"
|
// NB. Deferring the update by just setting /g_VideoForceFullRedraw/ is not an option, since this doesn't provide "flip-immediate"
|
||||||
//
|
//
|
||||||
// Ultimately this isn't the correct solution, and proper cycle-accurate video rendering should be done, but this is a much bigger job!
|
// Ultimately this isn't the correct solution, and proper cycle-accurate video rendering should be done, but this is a much bigger job!
|
||||||
// TODO: Is MemReadFloatingBus() still accurate now that we have proper per cycle video rendering??
|
// TODO-Michael: Is MemReadFloatingBus() still accurate now that we have proper per cycle video rendering??
|
||||||
|
|
||||||
if (!g_bVideoUpdatedThisFrame)
|
if (!g_bVideoUpdatedThisFrame)
|
||||||
{
|
{
|
||||||
|
@ -1323,20 +1322,42 @@ void VideoSetForceFullRedraw(void)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
DWORD VideoGetSnapshot(SS_IO_Video* pSS)
|
void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode)
|
||||||
{
|
{
|
||||||
pSS->bAltCharSet = !(g_nAltCharSetOffset == 0);
|
g_nAltCharSetOffset = !AltCharSet ? 0 : 256;
|
||||||
pSS->dwVidMode = g_uVideoMode;
|
g_uVideoMode = VideoMode;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//
|
||||||
|
|
||||||
DWORD VideoSetSnapshot(SS_IO_Video* pSS)
|
#define SS_YAML_KEY_ALTCHARSET "Alt Char Set"
|
||||||
|
#define SS_YAML_KEY_VIDEOMODE "Video Mode"
|
||||||
|
#define SS_YAML_KEY_CYCLESTHISFRAME "Cycles This Frame"
|
||||||
|
|
||||||
|
static std::string VideoGetSnapshotStructName(void)
|
||||||
{
|
{
|
||||||
g_nAltCharSetOffset = !pSS->bAltCharSet ? 0 : 256;
|
static const std::string name("Video");
|
||||||
g_uVideoMode = pSS->dwVidMode;
|
return name;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
void VideoSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", VideoGetSnapshotStructName().c_str());
|
||||||
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_ALTCHARSET, g_nAltCharSetOffset ? true : false);
|
||||||
|
yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_VIDEOMODE, g_uVideoMode);
|
||||||
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_CYCLESTHISFRAME, g_dwCyclesThisFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
|
||||||
|
{
|
||||||
|
if (!yamlLoadHelper.GetSubMap(VideoGetSnapshotStructName()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_nAltCharSetOffset = yamlLoadHelper.LoadBool(SS_YAML_KEY_ALTCHARSET) ? 256 : 0;
|
||||||
|
g_uVideoMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_VIDEOMODE);
|
||||||
|
g_dwCyclesThisFrame = yamlLoadHelper.LoadUint(SS_YAML_KEY_CYCLESTHISFRAME);
|
||||||
|
|
||||||
|
yamlLoadHelper.PopMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -152,12 +152,11 @@ struct WinBmpHeader4_t
|
||||||
|
|
||||||
extern HBITMAP g_hLogoBitmap;
|
extern HBITMAP g_hLogoBitmap;
|
||||||
|
|
||||||
extern COLORREF g_nMonochromeRGB; // saved
|
extern COLORREF g_nMonochromeRGB; // saved to Registry
|
||||||
extern uint32_t g_uVideoMode ;
|
extern uint32_t g_uVideoMode;
|
||||||
extern DWORD g_eVideoType ; // saved
|
extern DWORD g_eVideoType; // saved to Registry
|
||||||
extern DWORD g_uHalfScanLines; // saved
|
extern DWORD g_uHalfScanLines; // saved to Registry
|
||||||
extern uint8_t *g_pFramebufferbits;
|
extern uint8_t *g_pFramebufferbits;
|
||||||
extern int g_nAltCharSetOffset; // alternate character set
|
|
||||||
|
|
||||||
typedef bool (*VideoUpdateFuncPtr_t)(int,int,int,int,int);
|
typedef bool (*VideoUpdateFuncPtr_t)(int,int,int,int,int);
|
||||||
|
|
||||||
|
@ -177,7 +176,6 @@ void VideoReinitialize ();
|
||||||
void VideoResetState ();
|
void VideoResetState ();
|
||||||
WORD VideoGetScannerAddress(bool* pbVblBar_OUT, const DWORD uExecutedCycles);
|
WORD VideoGetScannerAddress(bool* pbVblBar_OUT, const DWORD uExecutedCycles);
|
||||||
bool VideoGetVbl(DWORD uExecutedCycles);
|
bool VideoGetVbl(DWORD uExecutedCycles);
|
||||||
void VideoEndOfVideoFrame(void);
|
|
||||||
|
|
||||||
bool VideoGetSW80COL(void);
|
bool VideoGetSW80COL(void);
|
||||||
bool VideoGetSWDHIRES(void);
|
bool VideoGetSWDHIRES(void);
|
||||||
|
@ -190,6 +188,10 @@ bool VideoGetSWAltCharSet(void);
|
||||||
|
|
||||||
void VideoSetForceFullRedraw(void);
|
void VideoSetForceFullRedraw(void);
|
||||||
|
|
||||||
|
void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode);
|
||||||
|
void VideoSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
|
void VideoLoadSnapshot(class YamlLoadHelper& yamlLoadHelper);
|
||||||
|
|
||||||
int _Video_SetupBanks( bool bBank2 );
|
int _Video_SetupBanks( bool bBank2 );
|
||||||
bool Update40ColCell (int x, int y, int xpixel, int ypixel, int offset);
|
bool Update40ColCell (int x, int y, int xpixel, int ypixel, int offset);
|
||||||
bool Update80ColCell (int x, int y, int xpixel, int ypixel, int offset);
|
bool Update80ColCell (int x, int y, int xpixel, int ypixel, int offset);
|
||||||
|
|
482
source/YamlHelper.cpp
Normal file
482
source/YamlHelper.cpp
Normal file
|
@ -0,0 +1,482 @@
|
||||||
|
/*
|
||||||
|
AppleWin : An Apple //e emulator for Windows
|
||||||
|
|
||||||
|
Copyright (C) 1994-1996, Michael O'Brien
|
||||||
|
Copyright (C) 1999-2001, Oliver Schmidt
|
||||||
|
Copyright (C) 2002-2005, Tom Charlesworth
|
||||||
|
Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski
|
||||||
|
|
||||||
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
AppleWin is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with AppleWin; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "Log.h"
|
||||||
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
|
int YamlHelper::InitParser(const char* pPathname)
|
||||||
|
{
|
||||||
|
m_hFile = fopen(pPathname, "r");
|
||||||
|
if (m_hFile == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!yaml_parser_initialize(&m_parser))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
yaml_parser_set_input_file(&m_parser, m_hFile);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlHelper::FinaliseParser(void)
|
||||||
|
{
|
||||||
|
if (m_hFile)
|
||||||
|
fclose(m_hFile);
|
||||||
|
|
||||||
|
m_hFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlHelper::GetNextEvent(bool bInMap /*= false*/)
|
||||||
|
{
|
||||||
|
if (!yaml_parser_parse(&m_parser, &m_newEvent))
|
||||||
|
{
|
||||||
|
//printf("Parser error %d\n", m_parser.error);
|
||||||
|
throw std::string("Parser error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int YamlHelper::GetScalar(std::string& scalar)
|
||||||
|
{
|
||||||
|
int res = 1;
|
||||||
|
bool bDone = false;
|
||||||
|
|
||||||
|
while (!bDone)
|
||||||
|
{
|
||||||
|
GetNextEvent();
|
||||||
|
|
||||||
|
switch(m_newEvent.type)
|
||||||
|
{
|
||||||
|
case YAML_SCALAR_EVENT:
|
||||||
|
scalar = m_scalarName = (const char*)m_newEvent.data.scalar.value;
|
||||||
|
res = 1;
|
||||||
|
bDone = true;
|
||||||
|
break;
|
||||||
|
case YAML_SEQUENCE_END_EVENT:
|
||||||
|
res = 0;
|
||||||
|
bDone = true;
|
||||||
|
break;
|
||||||
|
case YAML_MAPPING_END_EVENT:
|
||||||
|
res = 0;
|
||||||
|
bDone = true;
|
||||||
|
break;
|
||||||
|
case YAML_STREAM_END_EVENT:
|
||||||
|
res = 0;
|
||||||
|
bDone = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlHelper::GetMapStartEvent(void)
|
||||||
|
{
|
||||||
|
GetNextEvent();
|
||||||
|
|
||||||
|
if (m_newEvent.type != YAML_MAPPING_START_EVENT)
|
||||||
|
{
|
||||||
|
//printf("Unexpected yaml event (%d)\n", m_newEvent.type);
|
||||||
|
throw std::string("Unexpected yaml event");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int YamlHelper::ParseMap(MapYaml& mapYaml)
|
||||||
|
{
|
||||||
|
mapYaml.clear();
|
||||||
|
|
||||||
|
const char*& pValue = (const char*&) m_newEvent.data.scalar.value;
|
||||||
|
|
||||||
|
bool bKey = true;
|
||||||
|
char* pKey = NULL;
|
||||||
|
int res = 1;
|
||||||
|
bool bDone = false;
|
||||||
|
|
||||||
|
while (!bDone)
|
||||||
|
{
|
||||||
|
GetNextEvent(true);
|
||||||
|
|
||||||
|
switch(m_newEvent.type)
|
||||||
|
{
|
||||||
|
case YAML_STREAM_END_EVENT:
|
||||||
|
res = 0;
|
||||||
|
bDone = true;
|
||||||
|
break;
|
||||||
|
case YAML_MAPPING_START_EVENT:
|
||||||
|
{
|
||||||
|
MapValue mapValue;
|
||||||
|
mapValue.value = "";
|
||||||
|
mapValue.subMap = new MapYaml;
|
||||||
|
mapYaml[std::string(pKey)] = mapValue;
|
||||||
|
res = ParseMap(*mapValue.subMap);
|
||||||
|
if (!res)
|
||||||
|
throw std::string("ParseMap: premature end of file during map parsing");
|
||||||
|
bKey = true; // possibly more key,value pairs in this map
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case YAML_MAPPING_END_EVENT:
|
||||||
|
bDone = true;
|
||||||
|
break;
|
||||||
|
case YAML_SCALAR_EVENT:
|
||||||
|
if (bKey)
|
||||||
|
{
|
||||||
|
pKey = _strdup(pValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MapValue mapValue;
|
||||||
|
mapValue.value = pValue;
|
||||||
|
mapValue.subMap = NULL;
|
||||||
|
mapYaml[std::string(pKey)] = mapValue;
|
||||||
|
delete [] pKey; pKey = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bKey = bKey ? false : true;
|
||||||
|
break;
|
||||||
|
case YAML_SEQUENCE_START_EVENT:
|
||||||
|
case YAML_SEQUENCE_END_EVENT:
|
||||||
|
throw std::string("ParseMap: Sequence event unsupported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pKey)
|
||||||
|
delete [] pKey;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string YamlHelper::GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound)
|
||||||
|
{
|
||||||
|
MapYaml::const_iterator iter = mapYaml.find(key);
|
||||||
|
if (iter == mapYaml.end() || iter->second.subMap != NULL)
|
||||||
|
{
|
||||||
|
bFound = false; // not found
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string value = iter->second.value;
|
||||||
|
|
||||||
|
mapYaml.erase(iter);
|
||||||
|
|
||||||
|
bFound = true;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YamlHelper::GetSubMap(MapYaml** mapYaml, const std::string key)
|
||||||
|
{
|
||||||
|
MapYaml::const_iterator iter = (*mapYaml)->find(key);
|
||||||
|
if (iter == (*mapYaml)->end() || iter->second.subMap == NULL)
|
||||||
|
{
|
||||||
|
return false; // not found
|
||||||
|
}
|
||||||
|
|
||||||
|
*mapYaml = iter->second.subMap;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlHelper::GetMapRemainder(std::string& mapName, MapYaml& mapYaml)
|
||||||
|
{
|
||||||
|
for (MapYaml::iterator iter = mapYaml.begin(); iter != mapYaml.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (iter->second.subMap)
|
||||||
|
{
|
||||||
|
std::string subMapName(iter->first);
|
||||||
|
GetMapRemainder(subMapName, *iter->second.subMap);
|
||||||
|
delete iter->second.subMap;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char* pKey = iter->first.c_str();
|
||||||
|
LogOutput("%s: Unknown key (%s)\n", mapName.c_str(), pKey);
|
||||||
|
LogFileOutput("%s: Unknown key (%s)\n", mapName.c_str(), pKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapYaml.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
void YamlHelper::MakeAsciiToHexTable(void)
|
||||||
|
{
|
||||||
|
memset(m_AsciiToHex, -1, sizeof(m_AsciiToHex));
|
||||||
|
|
||||||
|
for (int i = '0'; i<= '9'; i++)
|
||||||
|
m_AsciiToHex[i] = i - '0';
|
||||||
|
|
||||||
|
for (int i = 'A'; i<= 'F'; i++)
|
||||||
|
m_AsciiToHex[i] = i - 'A' + 0xA;
|
||||||
|
|
||||||
|
for (int i = 'a'; i<= 'f'; i++)
|
||||||
|
m_AsciiToHex[i] = i - 'a' + 0xA;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlHelper::LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize)
|
||||||
|
{
|
||||||
|
for (MapYaml::iterator it = mapYaml.begin(); it != mapYaml.end(); ++it)
|
||||||
|
{
|
||||||
|
const char* pKey = it->first.c_str();
|
||||||
|
UINT addr = strtoul(pKey, NULL, 16);
|
||||||
|
if (addr >= kAddrSpaceSize)
|
||||||
|
throw std::string("Memory: line address too big: " + it->first);
|
||||||
|
|
||||||
|
LPBYTE pDst = (LPBYTE) (pMemBase + addr);
|
||||||
|
const LPBYTE pDstEnd = (LPBYTE) (pMemBase + kAddrSpaceSize);
|
||||||
|
|
||||||
|
if (it->second.subMap)
|
||||||
|
throw std::string("Memory: unexpected sub-map");
|
||||||
|
|
||||||
|
const char* pValue = it->second.value.c_str();
|
||||||
|
size_t len = strlen(pValue);
|
||||||
|
if (len & 1)
|
||||||
|
throw std::string("Memory: hex data must be an even number of nibbles on line address: " + it->first);
|
||||||
|
|
||||||
|
for (UINT i = 0; i<len; i+=2)
|
||||||
|
{
|
||||||
|
if (pDst >= pDstEnd)
|
||||||
|
throw std::string("Memory: hex data overflowed address space on line address: " + it->first);
|
||||||
|
|
||||||
|
BYTE ah = m_AsciiToHex[ (BYTE)(*pValue++) ];
|
||||||
|
BYTE al = m_AsciiToHex[ (BYTE)(*pValue++) ];
|
||||||
|
if ((ah | al) & 0x80)
|
||||||
|
throw std::string("Memory: hex data contains illegal character on line address: " + it->first);
|
||||||
|
|
||||||
|
*pDst++ = (ah<<4) | al;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapYaml.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
|
||||||
|
INT YamlLoadHelper::LoadInt(const std::string key)
|
||||||
|
{
|
||||||
|
bool bFound;
|
||||||
|
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
|
||||||
|
if (value == "")
|
||||||
|
{
|
||||||
|
m_bDoGetMapRemainder = false;
|
||||||
|
throw std::string(m_currentMapName + ": Missing: " + key);
|
||||||
|
}
|
||||||
|
return strtol(value.c_str(), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT YamlLoadHelper::LoadUint(const std::string key)
|
||||||
|
{
|
||||||
|
bool bFound;
|
||||||
|
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
|
||||||
|
if (value == "")
|
||||||
|
{
|
||||||
|
m_bDoGetMapRemainder = false;
|
||||||
|
throw std::string(m_currentMapName + ": Missing: " + key);
|
||||||
|
}
|
||||||
|
return strtoul(value.c_str(), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT64 YamlLoadHelper::LoadUint64(const std::string key)
|
||||||
|
{
|
||||||
|
bool bFound;
|
||||||
|
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
|
||||||
|
if (value == "")
|
||||||
|
{
|
||||||
|
m_bDoGetMapRemainder = false;
|
||||||
|
throw std::string(m_currentMapName + ": Missing: " + key);
|
||||||
|
}
|
||||||
|
return _strtoui64(value.c_str(), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YamlLoadHelper::LoadBool(const std::string key)
|
||||||
|
{
|
||||||
|
bool bFound;
|
||||||
|
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
|
||||||
|
if (value == "true")
|
||||||
|
return true;
|
||||||
|
else if (value == "false")
|
||||||
|
return false;
|
||||||
|
m_bDoGetMapRemainder = false;
|
||||||
|
throw std::string(m_currentMapName + ": Missing: " + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string YamlLoadHelper::LoadString_NoThrow(const std::string& key, bool& bFound)
|
||||||
|
{
|
||||||
|
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string YamlLoadHelper::LoadString(const std::string& key)
|
||||||
|
{
|
||||||
|
bool bFound;
|
||||||
|
std::string value = LoadString_NoThrow(key, bFound);
|
||||||
|
if (!bFound)
|
||||||
|
{
|
||||||
|
m_bDoGetMapRemainder = false;
|
||||||
|
throw std::string(m_currentMapName + ": Missing: " + key);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlLoadHelper::LoadMemory(const LPBYTE pMemBase, const size_t size)
|
||||||
|
{
|
||||||
|
m_yamlHelper.LoadMemory(*m_pMapYaml, pMemBase, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
|
||||||
|
void YamlSaveHelper::Save(const char* format, ...)
|
||||||
|
{
|
||||||
|
fwrite(m_szIndent, 1, m_indent, m_hFile);
|
||||||
|
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, format);
|
||||||
|
vfprintf(m_hFile, format, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveInt(const char* key, int value)
|
||||||
|
{
|
||||||
|
Save("%s: %d\n", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveUint(const char* key, UINT value)
|
||||||
|
{
|
||||||
|
Save("%s: %u\n", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveHexUint4(const char* key, UINT value)
|
||||||
|
{
|
||||||
|
Save("%s: 0x%01X\n", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveHexUint8(const char* key, UINT value)
|
||||||
|
{
|
||||||
|
Save("%s: 0x%02X\n", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveHexUint12(const char* key, UINT value)
|
||||||
|
{
|
||||||
|
Save("%s: 0x%03X\n", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveHexUint16(const char* key, UINT value)
|
||||||
|
{
|
||||||
|
Save("%s: 0x%04X\n", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveHexUint32(const char* key, UINT value)
|
||||||
|
{
|
||||||
|
Save("%s: 0x%08X\n", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveHexUint64(const char* key, UINT64 value)
|
||||||
|
{
|
||||||
|
Save("%s: 0x%016llX\n", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveBool(const char* key, bool value)
|
||||||
|
{
|
||||||
|
Save("%s: %s\n", key, value ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::SaveString(const char* key, const char* value)
|
||||||
|
{
|
||||||
|
Save("%s: %s\n", key, (value[0] != 0) ? value : "\"\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre: uMemSize must be multiple of 8
|
||||||
|
void YamlSaveHelper::SaveMemory(const LPBYTE pMemBase, const UINT uMemSize)
|
||||||
|
{
|
||||||
|
if (uMemSize & 7)
|
||||||
|
throw std::string("Memory: size must be multiple of 8");
|
||||||
|
|
||||||
|
const UINT kIndent = m_indent;
|
||||||
|
|
||||||
|
const UINT kStride = 64;
|
||||||
|
const char szHex[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
size_t lineSize = kIndent+6+2*kStride+2; // "AAAA: 00010203...3F\n\00" = 6+ 2*64 +2
|
||||||
|
char* const pLine = new char [lineSize];
|
||||||
|
|
||||||
|
for(DWORD dwOffset = 0x0000; dwOffset < uMemSize; dwOffset+=kStride)
|
||||||
|
{
|
||||||
|
char* pDst = pLine;
|
||||||
|
for (UINT i=0; i<kIndent; i++)
|
||||||
|
*pDst++ = ' ';
|
||||||
|
*pDst++ = szHex[ (dwOffset>>12)&0xf ];
|
||||||
|
*pDst++ = szHex[ (dwOffset>>8)&0xf ];
|
||||||
|
*pDst++ = szHex[ (dwOffset>>4)&0xf ];
|
||||||
|
*pDst++ = szHex[ dwOffset&0xf ];
|
||||||
|
*pDst++ = ':';
|
||||||
|
*pDst++ = ' ';
|
||||||
|
|
||||||
|
LPBYTE pMem = pMemBase + dwOffset;
|
||||||
|
|
||||||
|
for (UINT i=0; i<kStride; i+=8)
|
||||||
|
{
|
||||||
|
if (dwOffset + i >= uMemSize) // Support short final line (still multiple of 8 bytes)
|
||||||
|
{
|
||||||
|
lineSize = lineSize - 2*kStride + 2*i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE d;
|
||||||
|
d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf];
|
||||||
|
d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf];
|
||||||
|
d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf];
|
||||||
|
d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf];
|
||||||
|
|
||||||
|
d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf];
|
||||||
|
d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf];
|
||||||
|
d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf];
|
||||||
|
d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf];
|
||||||
|
}
|
||||||
|
|
||||||
|
*pDst++ = '\n';
|
||||||
|
*pDst = 0; // For debugger
|
||||||
|
|
||||||
|
fwrite(pLine, 1, lineSize-1, m_hFile); // -1 so don't write null terminator
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] pLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::FileHdr(UINT version)
|
||||||
|
{
|
||||||
|
fprintf(m_hFile, "%s:\n", SS_YAML_KEY_FILEHDR);
|
||||||
|
m_indent = 2;
|
||||||
|
SaveString(SS_YAML_KEY_TAG, SS_YAML_VALUE_AWSS);
|
||||||
|
SaveInt(SS_YAML_KEY_VERSION, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YamlSaveHelper::UnitHdr(std::string type, UINT version)
|
||||||
|
{
|
||||||
|
fprintf(m_hFile, "\n%s:\n", SS_YAML_KEY_UNIT);
|
||||||
|
m_indent = 2;
|
||||||
|
SaveString(SS_YAML_KEY_TYPE, type.c_str());
|
||||||
|
SaveInt(SS_YAML_KEY_VERSION, version);
|
||||||
|
}
|
266
source/YamlHelper.h
Normal file
266
source/YamlHelper.h
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "yaml.h"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_FILEHDR "File_hdr"
|
||||||
|
#define SS_YAML_KEY_TAG "Tag"
|
||||||
|
#define SS_YAML_KEY_VERSION "Version"
|
||||||
|
#define SS_YAML_KEY_UNIT "Unit"
|
||||||
|
#define SS_YAML_KEY_TYPE "Type"
|
||||||
|
#define SS_YAML_KEY_CARD "Card"
|
||||||
|
#define SS_YAML_KEY_STATE "State"
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_AWSS "AppleWin Save State"
|
||||||
|
|
||||||
|
struct MapValue;
|
||||||
|
typedef std::map<std::string, MapValue> MapYaml;
|
||||||
|
|
||||||
|
struct MapValue
|
||||||
|
{
|
||||||
|
std::string value;
|
||||||
|
MapYaml* subMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
class YamlHelper
|
||||||
|
{
|
||||||
|
friend class YamlLoadHelper; // YamlLoadHelper can access YamlHelper's private members
|
||||||
|
|
||||||
|
public:
|
||||||
|
YamlHelper(void) :
|
||||||
|
m_hFile(NULL)
|
||||||
|
{
|
||||||
|
MakeAsciiToHexTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
~YamlHelper(void)
|
||||||
|
{
|
||||||
|
if (m_hFile)
|
||||||
|
fclose(m_hFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitParser(const char* pPathname);
|
||||||
|
void FinaliseParser(void);
|
||||||
|
|
||||||
|
int GetScalar(std::string& scalar);
|
||||||
|
void GetMapStartEvent(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GetNextEvent(bool bInMap = false);
|
||||||
|
int ParseMap(MapYaml& mapYaml);
|
||||||
|
std::string GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound);
|
||||||
|
void LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize);
|
||||||
|
bool GetSubMap(MapYaml** mapYaml, const std::string key);
|
||||||
|
void GetMapRemainder(std::string& mapName, MapYaml& mapYaml);
|
||||||
|
|
||||||
|
void MakeAsciiToHexTable(void);
|
||||||
|
|
||||||
|
yaml_parser_t m_parser;
|
||||||
|
yaml_event_t m_newEvent;
|
||||||
|
|
||||||
|
std::string m_scalarName;
|
||||||
|
|
||||||
|
FILE* m_hFile;
|
||||||
|
char m_AsciiToHex[256];
|
||||||
|
|
||||||
|
MapYaml m_mapYaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
|
class YamlLoadHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
YamlLoadHelper(YamlHelper& yamlHelper)
|
||||||
|
: m_yamlHelper(yamlHelper),
|
||||||
|
m_pMapYaml(&yamlHelper.m_mapYaml),
|
||||||
|
m_bIteratingOverMap(false),
|
||||||
|
m_bDoGetMapRemainder(true),
|
||||||
|
m_topLevelMapName(yamlHelper.m_scalarName),
|
||||||
|
m_currentMapName(m_topLevelMapName)
|
||||||
|
{
|
||||||
|
if (!m_yamlHelper.ParseMap(yamlHelper.m_mapYaml))
|
||||||
|
{
|
||||||
|
m_bDoGetMapRemainder = false;
|
||||||
|
throw std::string(m_currentMapName + ": Failed to parse map");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~YamlLoadHelper(void)
|
||||||
|
{
|
||||||
|
if (m_bDoGetMapRemainder)
|
||||||
|
m_yamlHelper.GetMapRemainder(m_topLevelMapName, m_yamlHelper.m_mapYaml);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT LoadInt(const std::string key);
|
||||||
|
UINT LoadUint(const std::string key);
|
||||||
|
UINT64 LoadUint64(const std::string key);
|
||||||
|
bool LoadBool(const std::string key);
|
||||||
|
std::string LoadString_NoThrow(const std::string& key, bool& bFound);
|
||||||
|
std::string LoadString(const std::string& key);
|
||||||
|
void LoadMemory(const LPBYTE pMemBase, const size_t size);
|
||||||
|
|
||||||
|
bool GetSubMap(const std::string key)
|
||||||
|
{
|
||||||
|
YamlStackItem item = {m_pMapYaml, m_currentMapName};
|
||||||
|
m_stackMap.push(item);
|
||||||
|
bool res = m_yamlHelper.GetSubMap(&m_pMapYaml, key);
|
||||||
|
if (!res)
|
||||||
|
m_stackMap.pop();
|
||||||
|
else
|
||||||
|
m_currentMapName = key;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopMap(void)
|
||||||
|
{
|
||||||
|
if (m_stackMap.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
YamlStackItem item = m_stackMap.top();
|
||||||
|
m_stackMap.pop();
|
||||||
|
|
||||||
|
m_pMapYaml = item.pMapYaml;
|
||||||
|
m_currentMapName = item.mapName;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetMapNextSlotNumber(void)
|
||||||
|
{
|
||||||
|
if (!m_bIteratingOverMap)
|
||||||
|
{
|
||||||
|
m_iter = m_pMapYaml->begin();
|
||||||
|
m_bIteratingOverMap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_iter == m_pMapYaml->end())
|
||||||
|
{
|
||||||
|
m_bIteratingOverMap = false;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string scalar = m_iter->first;
|
||||||
|
++m_iter;
|
||||||
|
return scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
YamlHelper& m_yamlHelper;
|
||||||
|
MapYaml* m_pMapYaml;
|
||||||
|
bool m_bDoGetMapRemainder;
|
||||||
|
|
||||||
|
struct YamlStackItem
|
||||||
|
{
|
||||||
|
MapYaml* pMapYaml;
|
||||||
|
std::string mapName;
|
||||||
|
};
|
||||||
|
std::stack<YamlStackItem> m_stackMap;
|
||||||
|
|
||||||
|
std::string m_topLevelMapName;
|
||||||
|
std::string m_currentMapName;
|
||||||
|
|
||||||
|
bool m_bIteratingOverMap;
|
||||||
|
MapYaml::iterator m_iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
|
class YamlSaveHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
YamlSaveHelper(std::string pathname) :
|
||||||
|
m_hFile(NULL),
|
||||||
|
m_indent(0)
|
||||||
|
{
|
||||||
|
m_hFile = fopen(pathname.c_str(), "wt");
|
||||||
|
|
||||||
|
// todo: handle ERROR_ALREADY_EXISTS - ask if user wants to replace existing file
|
||||||
|
// - at this point any old file will have been truncated to zero
|
||||||
|
|
||||||
|
if(m_hFile == NULL)
|
||||||
|
throw std::string("Save error");
|
||||||
|
|
||||||
|
_tzset();
|
||||||
|
time_t ltime;
|
||||||
|
time(<ime);
|
||||||
|
char timebuf[26];
|
||||||
|
errno_t err = ctime_s(timebuf, sizeof(timebuf), <ime); // includes newline at end of string
|
||||||
|
fprintf(m_hFile, "# Date-stamp: %s\n", err == 0 ? timebuf : "Error: Datestamp\n\n");
|
||||||
|
|
||||||
|
fprintf(m_hFile, "---\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
memset(m_szIndent, ' ', kMaxIndent);
|
||||||
|
}
|
||||||
|
|
||||||
|
~YamlSaveHelper()
|
||||||
|
{
|
||||||
|
if (m_hFile)
|
||||||
|
{
|
||||||
|
fprintf(m_hFile, "...\n");
|
||||||
|
fclose(m_hFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Save(const char* format, ...);
|
||||||
|
|
||||||
|
void SaveInt(const char* key, int value);
|
||||||
|
void SaveUint(const char* key, UINT value);
|
||||||
|
void SaveHexUint4(const char* key, UINT value);
|
||||||
|
void SaveHexUint8(const char* key, UINT value);
|
||||||
|
void SaveHexUint12(const char* key, UINT value);
|
||||||
|
void SaveHexUint16(const char* key, UINT value);
|
||||||
|
void SaveHexUint32(const char* key, UINT value);
|
||||||
|
void SaveHexUint64(const char* key, UINT64 value);
|
||||||
|
void SaveBool(const char* key, bool value);
|
||||||
|
void SaveString(const char* key, const char* value);
|
||||||
|
void SaveMemory(const LPBYTE pMemBase, const UINT uMemSize);
|
||||||
|
|
||||||
|
class Label
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Label(YamlSaveHelper& rYamlSaveHelper, const char* format, ...) :
|
||||||
|
yamlSaveHelper(rYamlSaveHelper)
|
||||||
|
{
|
||||||
|
fwrite(yamlSaveHelper.m_szIndent, 1, yamlSaveHelper.m_indent, yamlSaveHelper.m_hFile);
|
||||||
|
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, format);
|
||||||
|
vfprintf(yamlSaveHelper.m_hFile, format, vl);
|
||||||
|
va_end(vl);
|
||||||
|
|
||||||
|
yamlSaveHelper.m_indent += 2;
|
||||||
|
_ASSERT(yamlSaveHelper.m_indent < yamlSaveHelper.kMaxIndent);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Label(void)
|
||||||
|
{
|
||||||
|
yamlSaveHelper.m_indent -= 2;
|
||||||
|
_ASSERT(yamlSaveHelper.m_indent >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
YamlSaveHelper& yamlSaveHelper;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Slot : public Label
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Slot(YamlSaveHelper& rYamlSaveHelper, std::string type, UINT slot, UINT version) :
|
||||||
|
Label(rYamlSaveHelper, "%d:\n", slot)
|
||||||
|
{
|
||||||
|
rYamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_CARD, type.c_str());
|
||||||
|
rYamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_VERSION, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Slot(void) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void FileHdr(UINT version);
|
||||||
|
void UnitHdr(std::string type, UINT version);
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE* m_hFile;
|
||||||
|
|
||||||
|
int m_indent;
|
||||||
|
static const UINT kMaxIndent = 50*2;
|
||||||
|
char m_szIndent[kMaxIndent];
|
||||||
|
};
|
|
@ -29,6 +29,7 @@
|
||||||
#include "..\AppleWin.h"
|
#include "..\AppleWin.h"
|
||||||
#include "..\CPU.h"
|
#include "..\CPU.h"
|
||||||
#include "..\Memory.h"
|
#include "..\Memory.h"
|
||||||
|
#include "..\YamlHelper.h"
|
||||||
|
|
||||||
|
|
||||||
#undef IN // Defined in windef.h
|
#undef IN // Defined in windef.h
|
||||||
|
@ -86,16 +87,20 @@ static BYTE reg_f2 = 0;
|
||||||
static BYTE reg_h2 = 0;
|
static BYTE reg_h2 = 0;
|
||||||
static BYTE reg_l2 = 0;
|
static BYTE reg_l2 = 0;
|
||||||
|
|
||||||
|
#if 0 // [AppleWin-TC] Not used
|
||||||
static int dma_request = 0;
|
static int dma_request = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
static BYTE *z80_bank_base;
|
static BYTE *z80_bank_base;
|
||||||
static int z80_bank_limit;
|
static int z80_bank_limit;
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 // [AppleWin-TC] Not used
|
||||||
void z80_trigger_dma(void)
|
void z80_trigger_dma(void)
|
||||||
{
|
{
|
||||||
dma_request = 1;
|
dma_request = 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void z80_reset(void)
|
void z80_reset(void)
|
||||||
{
|
{
|
||||||
|
@ -162,11 +167,11 @@ void z80_reset(void)
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if 0 // [AppleWin-TC]
|
||||||
static unsigned int z80_last_opcode_info;
|
static unsigned int z80_last_opcode_info;
|
||||||
|
|
||||||
#define LAST_OPCODE_INFO z80_last_opcode_info
|
#define LAST_OPCODE_INFO z80_last_opcode_info
|
||||||
|
|
||||||
#if 0 // [AppleWin-TC]
|
|
||||||
/* Remember the number of the last opcode. By default, the opcode does not
|
/* Remember the number of the last opcode. By default, the opcode does not
|
||||||
delay interrupt and does not change the I flag. */
|
delay interrupt and does not change the I flag. */
|
||||||
#define SET_LAST_OPCODE(x) \
|
#define SET_LAST_OPCODE(x) \
|
||||||
|
@ -463,6 +468,9 @@ static void export_registers(void)
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// [AppleWin-TC] Z80 IRQs not supported
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Interrupt handling. */
|
/* Interrupt handling. */
|
||||||
|
|
||||||
#define DO_INTERRUPT(int_kind) \
|
#define DO_INTERRUPT(int_kind) \
|
||||||
|
@ -533,6 +541,7 @@ static void export_registers(void)
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -6330,7 +6339,7 @@ DWORD z80_mainloop(ULONG uTotalCycles, ULONG uExecutedCycles)
|
||||||
|
|
||||||
//cpu_int_status->num_dma_per_opcode = 0; // [AppleWin-TC] Not used
|
//cpu_int_status->num_dma_per_opcode = 0; // [AppleWin-TC] Not used
|
||||||
|
|
||||||
if (g_ActiveCPU != CPU_Z80) // [AppleWin-TC]
|
if (GetActiveCpu() != CPU_Z80) // [AppleWin-TC]
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//} while (!dma_request);
|
//} while (!dma_request);
|
||||||
|
@ -6422,3 +6431,139 @@ void z80_WRMEM(WORD Addr, BYTE Value)
|
||||||
}
|
}
|
||||||
CpuWrite( addr, Value, ConvertZ80TStatesTo6502Cycles(maincpu_clk) );
|
CpuWrite( addr, Value, ConvertZ80TStatesTo6502Cycles(maincpu_clk) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
#define SS_YAML_VALUE_CARD_Z80 "Z80"
|
||||||
|
|
||||||
|
#define SS_YAML_KEY_REGA "A"
|
||||||
|
#define SS_YAML_KEY_REGB "B"
|
||||||
|
#define SS_YAML_KEY_REGC "C"
|
||||||
|
#define SS_YAML_KEY_REGD "D"
|
||||||
|
#define SS_YAML_KEY_REGE "E"
|
||||||
|
#define SS_YAML_KEY_REGF "F"
|
||||||
|
#define SS_YAML_KEY_REGH "H"
|
||||||
|
#define SS_YAML_KEY_REGL "L"
|
||||||
|
#define SS_YAML_KEY_REGIX "IX"
|
||||||
|
#define SS_YAML_KEY_REGIY "IY"
|
||||||
|
#define SS_YAML_KEY_REGSP "SP"
|
||||||
|
#define SS_YAML_KEY_REGPC "PC"
|
||||||
|
#define SS_YAML_KEY_REGI "I"
|
||||||
|
#define SS_YAML_KEY_REGR "R"
|
||||||
|
#define SS_YAML_KEY_IFF1 "IFF1"
|
||||||
|
#define SS_YAML_KEY_IFF2 "IFF2"
|
||||||
|
#define SS_YAML_KEY_IM_MODE "IM Mode"
|
||||||
|
#define SS_YAML_KEY_REGA2 "A'"
|
||||||
|
#define SS_YAML_KEY_REGB2 "B'"
|
||||||
|
#define SS_YAML_KEY_REGC2 "C'"
|
||||||
|
#define SS_YAML_KEY_REGD2 "D'"
|
||||||
|
#define SS_YAML_KEY_REGE2 "E'"
|
||||||
|
#define SS_YAML_KEY_REGF2 "F'"
|
||||||
|
#define SS_YAML_KEY_REGH2 "H'"
|
||||||
|
#define SS_YAML_KEY_REGL2 "L'"
|
||||||
|
#define SS_YAML_KEY_ACTIVE "Active"
|
||||||
|
|
||||||
|
std::string Z80_GetSnapshotCardName(void)
|
||||||
|
{
|
||||||
|
static const std::string name(SS_YAML_VALUE_CARD_Z80);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
|
||||||
|
{
|
||||||
|
YamlSaveHelper::Slot slot(yamlSaveHelper, Z80_GetSnapshotCardName(), uSlot, 1); // fixme: object should know its slot
|
||||||
|
|
||||||
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
|
// SoftCard SW & HW details: http://apple2info.net/images/f/f0/SC-SWHW.pdf
|
||||||
|
// . SoftCard uses the Apple II's DMA circuit to pause the 6502 (no CLK to 6502)
|
||||||
|
// . But: "In Apple II DMA, the 6502 CPU will die after approximately 15 clocks because it depends on the clock to refresh its internal registers."
|
||||||
|
// ref: Apple Tech Note: https://archive.org/stream/IIe_2523004_RDY_Line/IIe_2523004_RDY_Line_djvu.txt
|
||||||
|
// NB. Not for 65C02 which is a static processor.
|
||||||
|
// . SoftCard controls the 6502's RDY line to periodically allow only 1 memory fetch by 6502 (ie. the opcode fetch)
|
||||||
|
//
|
||||||
|
// So save ActiveCPU to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card)
|
||||||
|
//
|
||||||
|
// NB. Save-state only occurs when message pump runs:
|
||||||
|
// . ie. at end of 1ms emulation burst
|
||||||
|
// Either 6502 or Z80 could be active.
|
||||||
|
//
|
||||||
|
|
||||||
|
yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, GetActiveCpu() == CPU_Z80 ? 1 : 0);
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGA, reg_a);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGB, reg_b);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGC, reg_c);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGD, reg_d);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGE, reg_e);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGF, reg_f);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGH, reg_h);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGL, reg_l);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGIX, ((USHORT)reg_ixh<<8)|(USHORT)reg_ixl);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGIY, ((USHORT)reg_iyh<<8)|(USHORT)reg_iyl);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGSP, reg_sp);
|
||||||
|
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGPC, (USHORT)z80_reg_pc);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGI, reg_i);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGR, reg_r);
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IFF1, iff1);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IFF2, iff2);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IM_MODE, im_mode);
|
||||||
|
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGA2, reg_a2);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGB2, reg_b2);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGC2, reg_c2);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGD2, reg_d2);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGE2, reg_e2);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGF2, reg_f2);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGH2, reg_h2);
|
||||||
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGL2, reg_l2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT version)
|
||||||
|
{
|
||||||
|
if (uSlot != 4 && uSlot != 5) // fixme
|
||||||
|
throw std::string("Card: wrong slot");
|
||||||
|
|
||||||
|
if (version != 1)
|
||||||
|
throw std::string("Card: wrong version");
|
||||||
|
|
||||||
|
reg_a = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGA);
|
||||||
|
reg_b = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGB);
|
||||||
|
reg_c = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGC);
|
||||||
|
reg_d = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGD);
|
||||||
|
reg_e = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGE);
|
||||||
|
reg_f = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGF);
|
||||||
|
reg_h = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGH);
|
||||||
|
reg_l = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGL);
|
||||||
|
USHORT IX = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGIX);
|
||||||
|
reg_ixh = IX >> 8;
|
||||||
|
reg_ixl = IX & 0xFF;
|
||||||
|
USHORT IY = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGIY);
|
||||||
|
reg_iyh = IY >> 8;
|
||||||
|
reg_iyl = IY & 0xFF;
|
||||||
|
reg_sp = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGSP);
|
||||||
|
z80_reg_pc = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGPC);
|
||||||
|
reg_i = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGI);
|
||||||
|
reg_r = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGR);
|
||||||
|
|
||||||
|
iff1 = yamlLoadHelper.LoadUint(SS_YAML_KEY_IFF1);
|
||||||
|
iff2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_IFF2);
|
||||||
|
im_mode = yamlLoadHelper.LoadUint(SS_YAML_KEY_IM_MODE);
|
||||||
|
|
||||||
|
reg_a2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGA2);
|
||||||
|
reg_b2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGB2);
|
||||||
|
reg_c2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGC2);
|
||||||
|
reg_d2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGD2);
|
||||||
|
reg_e2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGE2);
|
||||||
|
reg_f2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGF2);
|
||||||
|
reg_h2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGH2);
|
||||||
|
reg_l2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGL2);
|
||||||
|
|
||||||
|
export_registers();
|
||||||
|
|
||||||
|
if ( yamlLoadHelper.LoadUint(SS_YAML_KEY_ACTIVE) )
|
||||||
|
SetActiveCpu(CPU_Z80); // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time)
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ typedef struct z80_regs_s {
|
||||||
WORD reg_hl2;
|
WORD reg_hl2;
|
||||||
} z80_regs_t;
|
} z80_regs_t;
|
||||||
|
|
||||||
|
#if 0 // [AppleWin-TC]: unused, so comment out
|
||||||
#define Z80_REGS_GET_AF(reg_ptr) ((reg_ptr)->reg_af)
|
#define Z80_REGS_GET_AF(reg_ptr) ((reg_ptr)->reg_af)
|
||||||
#define Z80_REGS_GET_BC(reg_ptr) ((reg_ptr)->reg_bc)
|
#define Z80_REGS_GET_BC(reg_ptr) ((reg_ptr)->reg_bc)
|
||||||
#define Z80_REGS_GET_DE(reg_ptr) ((reg_ptr)->reg_de)
|
#define Z80_REGS_GET_DE(reg_ptr) ((reg_ptr)->reg_de)
|
||||||
|
@ -75,6 +76,7 @@ typedef struct z80_regs_s {
|
||||||
#define Z80_REGS_SET_BC2(reg_ptr, val) ((reg_ptr)->reg_bc2 = (val))
|
#define Z80_REGS_SET_BC2(reg_ptr, val) ((reg_ptr)->reg_bc2 = (val))
|
||||||
#define Z80_REGS_SET_DE2(reg_ptr, val) ((reg_ptr)->reg_de2 = (val))
|
#define Z80_REGS_SET_DE2(reg_ptr, val) ((reg_ptr)->reg_de2 = (val))
|
||||||
#define Z80_REGS_SET_HL2(reg_ptr, val) ((reg_ptr)->reg_hl2 = (val))
|
#define Z80_REGS_SET_HL2(reg_ptr, val) ((reg_ptr)->reg_hl2 = (val))
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "AppleWin.h"
|
#include "AppleWin.h"
|
||||||
|
#include "CPU.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "z80emu.h"
|
#include "z80emu.h"
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ BYTE __stdcall CPMZ80_IONull(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULON
|
||||||
BYTE __stdcall CPMZ80_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
|
BYTE __stdcall CPMZ80_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
|
||||||
{
|
{
|
||||||
if ((uAddr & 0xFF00) == (0xC000 + (g_uCPMZ80Slot << 8)))
|
if ((uAddr & 0xFF00) == (0xC000 + (g_uCPMZ80Slot << 8)))
|
||||||
g_ActiveCPU = (g_ActiveCPU == CPU_6502) ? CPU_Z80 : CPU_6502;
|
SetActiveCpu( GetActiveCpu() == CPU_Z80 ? GetMainCpu() : CPU_Z80 );
|
||||||
|
|
||||||
return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
|
return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,3 +14,8 @@
|
||||||
|
|
||||||
// Protótipos
|
// Protótipos
|
||||||
void ConfigureSoftcard(LPBYTE pCxRomPeripheral, UINT uSlot);
|
void ConfigureSoftcard(LPBYTE pCxRomPeripheral, UINT uSlot);
|
||||||
|
|
||||||
|
// NB. These are in z80.cpp:
|
||||||
|
std::string Z80_GetSnapshotCardName(void);
|
||||||
|
void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
|
||||||
|
bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT version);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user