mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-06-08 16:29:39 +00:00
Merge branch 'master' into MB-class2
This commit is contained in:
commit
0bca091b55
|
@ -1,57 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Applewin", "AppleWinExpress2008.vcproj", "{1DA0C491-B5F4-4EC8-B1D2-CF6BE635DADC}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}
|
||||
{7935B998-C713-42AE-8F6D-9FF9080A1B1B} = {7935B998-C713-42AE-8F6D-9FF9080A1B1B}
|
||||
{2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2} = {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}
|
||||
{709278B8-C583-4BD8-90DE-4E4F35A3BD8B} = {709278B8-C583-4BD8-90DE-4E4F35A3BD8B}
|
||||
{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB} = {0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib-Express2008.vcproj", "{7935B998-C713-42AE-8F6D-9FF9080A1B1B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zip_lib", "zip_lib\zip_lib2008.vcproj", "{709278B8-C583-4BD8-90DE-4E4F35A3BD8B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestCPU6502", "test\TestCPU6502\TestCPU6502-vs2008.vcproj", "{2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml", "libyaml\win32\yaml2008.vcproj", "{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestDebugger", "test\TestDebugger\TestDebugger.vcproj", "{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1DA0C491-B5F4-4EC8-B1D2-CF6BE635DADC}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1DA0C491-B5F4-4EC8-B1D2-CF6BE635DADC}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1DA0C491-B5F4-4EC8-B1D2-CF6BE635DADC}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1DA0C491-B5F4-4EC8-B1D2-CF6BE635DADC}.Release|Win32.Build.0 = Release|Win32
|
||||
{7935B998-C713-42AE-8F6D-9FF9080A1B1B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7935B998-C713-42AE-8F6D-9FF9080A1B1B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7935B998-C713-42AE-8F6D-9FF9080A1B1B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7935B998-C713-42AE-8F6D-9FF9080A1B1B}.Release|Win32.Build.0 = Release|Win32
|
||||
{709278B8-C583-4BD8-90DE-4E4F35A3BD8B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{709278B8-C583-4BD8-90DE-4E4F35A3BD8B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{709278B8-C583-4BD8-90DE-4E4F35A3BD8B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{709278B8-C583-4BD8-90DE-4E4F35A3BD8B}.Release|Win32.Build.0 = Release|Win32
|
||||
{2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Release|Win32.Build.0 = Release|Win32
|
||||
{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Release|Win32.Build.0 = Release|Win32
|
||||
{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0AE28CF0-15B0-4DDF-B6D2-4562D8E456BB}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
File diff suppressed because it is too large
Load Diff
|
@ -53,6 +53,7 @@
|
|||
<ClInclude Include="source\Configuration\PropertySheet.h" />
|
||||
<ClInclude Include="source\Configuration\PropertySheetDefs.h" />
|
||||
<ClInclude Include="source\Configuration\PropertySheetHelper.h" />
|
||||
<ClInclude Include="source\CopyProtectionDongles.h" />
|
||||
<ClInclude Include="source\Core.h" />
|
||||
<ClInclude Include="source\CPU.h" />
|
||||
<ClInclude Include="source\CPU\cpu6502.h" />
|
||||
|
@ -115,6 +116,8 @@
|
|||
<ClInclude Include="source\StrFormat.h" />
|
||||
<ClInclude Include="source\SynchronousEventManager.h" />
|
||||
<ClInclude Include="source\Tape.h" />
|
||||
<ClInclude Include="source\Tfe\DNS.h" />
|
||||
<ClInclude Include="source\Tfe\IPRaw.h" />
|
||||
<ClInclude Include="source\Tfe\NetworkBackend.h" />
|
||||
<ClInclude Include="source\Tfe\Bpf.h" />
|
||||
<ClInclude Include="source\Tfe\Ip6_misc.h" />
|
||||
|
@ -157,6 +160,7 @@
|
|||
<ClCompile Include="source\CardManager.cpp" />
|
||||
<ClCompile Include="source\CmdLine.cpp" />
|
||||
<ClCompile Include="source\Configuration\About.cpp" />
|
||||
<ClCompile Include="source\Configuration\Config.cpp" />
|
||||
<ClCompile Include="source\Configuration\PageAdvanced.cpp" />
|
||||
<ClCompile Include="source\Configuration\PageConfig.cpp" />
|
||||
<ClCompile Include="source\Configuration\PageConfigTfe.cpp" />
|
||||
|
@ -165,6 +169,7 @@
|
|||
<ClCompile Include="source\Configuration\PageSound.cpp" />
|
||||
<ClCompile Include="source\Configuration\PropertySheet.cpp" />
|
||||
<ClCompile Include="source\Configuration\PropertySheetHelper.cpp" />
|
||||
<ClCompile Include="source\CopyProtectionDongles.cpp" />
|
||||
<ClCompile Include="source\Core.cpp" />
|
||||
<ClCompile Include="source\CPU.cpp" />
|
||||
<ClCompile Include="source\Debugger\Debugger_Disassembler.cpp" />
|
||||
|
@ -224,6 +229,8 @@
|
|||
<ClCompile Include="source\StrFormat.cpp" />
|
||||
<ClCompile Include="source\SynchronousEventManager.cpp" />
|
||||
<ClCompile Include="source\Tape.cpp" />
|
||||
<ClCompile Include="source\Tfe\DNS.cpp" />
|
||||
<ClCompile Include="source\Tfe\IPRaw.cpp" />
|
||||
<ClCompile Include="source\Tfe\NetworkBackend.cpp" />
|
||||
<ClCompile Include="source\Tfe\PCapBackend.cpp" />
|
||||
<ClCompile Include="source\Tfe\tfearch.cpp">
|
||||
|
@ -469,7 +476,7 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.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;shlwapi.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.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;shlwapi.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
</Link>
|
||||
|
@ -497,7 +504,7 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;ddraw_lib\x86\dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw_lib\x86\ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;ddraw_lib\x86\dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw_lib\x86\ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
</Link>
|
||||
|
@ -524,7 +531,7 @@
|
|||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.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;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.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;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
</Link>
|
||||
|
@ -555,7 +562,7 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.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;shlwapi.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.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;shlwapi.lib;ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
|
@ -588,7 +595,7 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;ddraw_lib\x86\dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw_lib\x86\ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;ddraw_lib\x86\dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;shlwapi.lib;ddraw_lib\x86\ddraw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
|
@ -621,7 +628,7 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>htmlhelp.lib;comctl32.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;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>iphlpapi.lib;htmlhelp.lib;comctl32.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;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||
|
|
|
@ -259,6 +259,18 @@
|
|||
<ClCompile Include="source\Uthernet2.cpp">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Tfe\IPRaw.cpp">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Tfe\DNS.cpp">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\Configuration\Config.cpp">
|
||||
<Filter>Source Files\Configuration</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\CopyProtectionDongles.cpp">
|
||||
<Filter>Source Files\Emulator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\MockingboardCardManager.cpp">
|
||||
<Filter>Source Files\Emulator</Filter>
|
||||
</ClCompile>
|
||||
|
@ -597,6 +609,15 @@
|
|||
<ClInclude Include="source\Uthernet2.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Tfe\IPRaw.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\Tfe\DNS.h">
|
||||
<Filter>Source Files\Uthernet</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\CopyProtectionDongles.h">
|
||||
<Filter>Source Files\Emulator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\MockingboardCardManager.h">
|
||||
<Filter>Source Files\Emulator</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -24,20 +24,44 @@ Before submitting an enhancement, search the existing issues to see if this enha
|
|||
|
||||
### Pull Requests
|
||||
|
||||
The process described here has several goals:
|
||||
- Maintain AppleWin's quality
|
||||
- Enforce a workable solution for AppleWin maintainers to review contributions
|
||||
Thank you for wanting to make the project better! However, before you submit a PR (Pull Request) please read the following carefully as the process described here has several goals:
|
||||
|
||||
Please review the simple [Coding Conventions](https://github.com/AppleWin/AppleWin/blob/master/docs/CodingConventions.txt).
|
||||
- Maintain AppleWin's quality,
|
||||
- Enforce a workable solution for AppleWin maintainers to review contributions, and
|
||||
- Explain the development philosophy.
|
||||
|
||||
Smaller PRs are highly desirable, as they should be simpler to review and approve. Large changes are likely to be rejected or not get looked at (resulting in them going stale, and ultimately diverging further from the mainline repo).
|
||||
Firstly,
|
||||
|
||||
# Do NOT submit one big patch!
|
||||
|
||||
The AppleWin developers work on AppleWin in their spare time. This means we have limited time to review PRs. Smaller PRs are highly desirable, as they should be simpler to review and approve. Large changes are likely to be rejected or not get looked at (resulting in them going stale, and ultimately diverging further from the mainline repo).
|
||||
|
||||
For large changes being submitted for review, then it's HIGHLY recommended to split the large PR into smaller PRs, and submit them piece by piece. This means that no dependencies can exist between each smaller PR.
|
||||
|
||||
For a PR, don't make changes that are unrelated to the PR. These can be done in separate PRs.
|
||||
For a PR, don't make changes that are unrelated to the PR as this adds unnecessary noise and time to review. These can and should be done in separate PRs.
|
||||
|
||||
Follow the coding style in the source file(s) that are being changed. Since this is a mature codebase, then bear in mind that different coding styles can exist in different source files.
|
||||
Next, please make sure your code matches the existing style by reviewing the simple [Coding Conventions](https://github.com/AppleWin/AppleWin/blob/master/docs/CodingConventions.txt).
|
||||
|
||||
Follow the coding style in the source file(s) that are being changed. Since this is a mature codebase, then bear in mind that different coding styles can and do exist in different source files due to many different authors over the past 25+ years.
|
||||
|
||||
For new (large) features, then link the PR back to an enhancement issue, where the proposed feature had been discussed with AppleWin maintainers first and justified using suitable use-cases. In this enhancement issue be sure to include a specification of the feature, and a design if necessary. Having a design (doc, diagrams) that explains the logic/algorithms/protocol etc will help in the long term maintenance of this feature.
|
||||
|
||||
When changing project metadata files (eg. .sln, .vcproj, .rc) then different versions of Visual Studio may decide to reorder or re-format other sections of the file. This can result in lots of churn in the file each time a trivial edit is made. So before committing the PR, check the difference, and if there's been lots of unnecessary changes then just make the required change using a non-Visual Studio editor.
|
||||
|
||||
When submitting UI changes please discuss WHY you are making changes.
|
||||
|
||||
* **Our userbase expects things to work the way they are used to.** Changing default behavior without a "migration path" causes users to submit bug reports asking us to revert changes which wastes everyone's time.
|
||||
|
||||
* **Functionality should be prioritized over Form.** The _entire_ point of UI is to empower the user to do the thing they want to do and _then get out of their way._ A pretty UI, but one that frustrates users, is not empowering them.
|
||||
|
||||
* Also keep in mind many so called modern UI/UX "experts" tend to make changes for the sake of change in order to sell a product. Worse they tend to focus on mobile design even when it makes little or no sense on a desktop platform. There is a time and a place to focus on Form but as a mature project we are more interested in stability and functionality than throwing on a fresh coat of paint that more likely introduces a new set of bugs.
|
||||
|
||||
Understand that not everyone will agree to UI changes. The developers have been using computers a very long time and are not interested in chasing modern UI fads unless a good reason can be shown _why_ the UI should be changed. For example, take a poll, or even better raise an issue asking for feedback. This way we have hard data showing that there is interest instead of assuming that a change is automatically "better".
|
||||
|
||||
Trivial changes such as updating art are much easier to accept than rewriting the UI moving buttons around.
|
||||
|
||||
When discussing topics focus on the problem and potential solutions and not people. Please keep things professional.
|
||||
|
||||
Lasty, there are many reasons why we may reject a feature or PR. This does NOT mean we aren't interested; it just means that the feature or PR doesn't meet the developer's expectations and project goals _at this time._
|
||||
|
||||
Thanks again for your interest in wanting to make AppleWin better.
|
||||
|
|
17
README.md
17
README.md
|
@ -5,7 +5,7 @@ AppleWin
|
|||
|
||||
AppleWin is a fully-featured emulator supporting different Apple II models and clones. A variety of peripheral cards and video display modes are supported (eg. NTSC, RGB); and there's an extensive built-in symbolic debugger.
|
||||
|
||||
Peripheral cards supported:
|
||||
Peripheral cards and add-on hardware supported:
|
||||
- Mockingboard, Phasor and SAM sound cards
|
||||
- Disk II interface for floppy disk drives
|
||||
- Hard disk controller
|
||||
|
@ -13,16 +13,18 @@ Peripheral cards supported:
|
|||
- Parallel printer card
|
||||
- Mouse interface
|
||||
- Apple IIe Extended 80-Column Text Card and RamWorks III (8MB)
|
||||
- RGB cards: Apple's Extended 80-Column Text/AppleColor Adaptor Card, 'Le Chat Mauve' Féline and Eve.
|
||||
- RGB cards: Apple's Extended 80-Column Text/AppleColor Adaptor Card and 'Le Chat Mauve' Féline.
|
||||
- CP/M SoftCard
|
||||
- Uthernet I (ethernet card)
|
||||
- Uthernet I and II (ethernet cards)
|
||||
- Language Card and Saturn 64/128K for Apple II/II+
|
||||
- 4Play and SNES MAX joystick cards
|
||||
- VidHD card (functionality limited to IIgs' Super Hi-Res video modes)
|
||||
- No Slot Clock (NSC)
|
||||
|
||||
|
||||
Download latest (stable) release: [AppleWin v1.29.16.0](https://github.com/AppleWin/AppleWin/releases/download/v1.29.16.0/AppleWin1.29.16.0.zip)
|
||||
Download latest (stable) release: [AppleWin v1.30.13.0](https://github.com/AppleWin/AppleWin/releases/download/v1.30.13.0/AppleWin1.30.13.0.zip)
|
||||
|
||||
Release Notes: [v1.29.16.0](https://github.com/AppleWin/AppleWin/releases/tag/v1.29.16.0)
|
||||
Release Notes: [v1.30.13.0](https://github.com/AppleWin/AppleWin/releases/tag/v1.30.13.0)
|
||||
|
||||
|
||||
Building
|
||||
|
@ -32,6 +34,11 @@ To compile from source see:
|
|||
* [docs/compiling.txt](https://github.com/AppleWin/AppleWin/blob/master/docs/compiling.txt)
|
||||
|
||||
|
||||
Contributing
|
||||
============
|
||||
Please see the [CONTRIBUTING](https://github.com/AppleWin/AppleWin/blob/master/CONTRIBUTING.md) doc before raising new bugs, features and _especially_ PRs.
|
||||
|
||||
|
||||
Next Version
|
||||
============
|
||||
Experimental build: pending
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; Apple 2 Applesoft Symbol Table
|
||||
; Version 3 Fix AppleWin GH#1144
|
||||
; Version 2 Cross-referenced/Sync'd with APPLE2E.SYM & A2_BASIC.SYM
|
||||
; Version 1 by Michael Pohoreski - AppleWin Debugger Dev
|
||||
; Based on Bob Sander-Cederlof's "S-C DocuMentor: Applesoft"
|
||||
|
@ -562,13 +563,14 @@ EA2B OUTOFRNG
|
|||
DB5A OUTQUES
|
||||
DB57 OUTSP
|
||||
E8D5 OVERFLOW
|
||||
79 P.ADD
|
||||
50 P.AND
|
||||
7B P.MUL
|
||||
7F P.NEQ
|
||||
46 P.OR
|
||||
7D P.PWR
|
||||
64 P.REL
|
||||
; NB. these 7 P.xxx values are constants used in MATHTBL (a MATH OPERATOR BRANCH TABLE) - see AppleWin GH#1144
|
||||
; 79 P.ADD
|
||||
; 50 P.AND
|
||||
; 7B P.MUL
|
||||
; 7F P.NEQ
|
||||
; 46 P.OR
|
||||
; 7D P.PWR
|
||||
; 64 P.REL
|
||||
DEB2 PARCHK
|
||||
D56C PARSE
|
||||
.01=D56D .02=D578 .03=D588 .04=D590 .05=D5A2 .06=D5A7 .07=D5A8
|
||||
|
|
|
@ -8,6 +8,97 @@ https://github.com/AppleWin/AppleWin/issues/new
|
|||
|
||||
Tom Charlesworth
|
||||
|
||||
|
||||
1.30.13.0 - 2 Jan 2023
|
||||
----------------------
|
||||
. [Change #1153] Support Game I/O Connector copy protection dongles. [@medasaro]
|
||||
- SDS SpeedStar dongle
|
||||
. [Change #1141,1142,1148,1149,1150] SNES MAX support for various controllers via mapping files. [@eriknoc]
|
||||
- EG. -snes-max-user-joy1 snesmax\controller_Logitech_F310.yaml
|
||||
. [Change #1134] Add disk activity indicators for drives in Slot 5.
|
||||
- Only visible in 2x Windowed mode.
|
||||
- Add a new UI toggle in Config->Disk tab to "Show status" (ie. the track/sector status).
|
||||
- Hovering over this status will show a tooltip with both decimal and hexadecimal values,
|
||||
and the track includes the full fractional quarter track value too.
|
||||
. [Change #1133] Add a new command line '-s<n> diskii13' to put a diskii card into slot-n and force it to use the 13-sector firmware.
|
||||
. [Bug #1157] Fix video junk on RHS edge for TV & Monitor video modes. (Regression at 1.13.11.0)
|
||||
. [Bug #1144] Fix some ZP symbols in A2_BASIC.SYM.
|
||||
. [Bug #1143] Fix graphical glitches on penultimate scan line when in non-"50% Scan Lines" mode.
|
||||
. [Bug #1138] Fix Mousecard - wasn't generating VBL interrupt for mode byte of $08. Fixes 'Jeeves'.
|
||||
. [Bug #1131] Fix MIXED issue when in 'Color (PAL Monitor)' video mode.
|
||||
. Change: Debugger: for LBR, support the unset/undefined case (eg. reset to undefined when beginning a new debug session).
|
||||
. Change: Debugger: extend to support DISK commands for Disk II cards in other slots:
|
||||
- DISK SLOT n
|
||||
- Now DISK INFO will provide info for the new slot.
|
||||
. Change: Debugger: add new command: 'bpv <vpos,[len]>'
|
||||
- break when video-scanner's vertical position matches vpos.
|
||||
- NB. auto disable when hit.
|
||||
. Change: Debugger: extend watches: 'WA <n> v' to show video scanner address & video data (aux and/or main or shr 4-byte).
|
||||
|
||||
|
||||
1.30.12.0 - 27 Sep 2022
|
||||
-----------------------
|
||||
. [Bug #1128] Increase paddle maximum offset - fixes 'Learning with Leepers'.
|
||||
. [Bug #1127] Debugger: fix memory search command.
|
||||
. [Bug #1126] Fix rare crash bug (when unprotected WOZ in drive).
|
||||
. [Bug #1125] Improve WOZ support: fixes 'Accolade Comics'.
|
||||
. [Bug #1121] Fix for aspect ratio in full-screen:
|
||||
- Now revert to uniformly scaling in both x & y directions unless user specifies resolution.
|
||||
- NB. Regression at 1.30.7.0 when adding VidHD support.
|
||||
. [Bug #1119] Fix render issue in 'Color (PAL Monitor)' video mode.
|
||||
. [Bug #1022] WOZ support: Better cross-track positioning - fixes 'Balance of Power'.
|
||||
. Fix for loading old save-states with Phasor card (bumps MB version in save-state to v9).
|
||||
- NB. Regression at 1.30.10.0 when fixed Phasor to "use correct primary AY8913".
|
||||
. Change: Command line: support '-s2 ssc'.
|
||||
|
||||
|
||||
1.30.11.0 - 23 Jun 2022
|
||||
-----------------------
|
||||
. [Change #1103] Debugger: support memory breakpoints for HDD DMA r/w's:
|
||||
- When the debugger is active (eg. breakpoints enabled) then trap on HDD r/w's that match the BPM[R|W].
|
||||
- NB. the breakpoint will fire after the whole HDD r/w operation has completed.
|
||||
. [Bug #1113] Fix for Uthernet II registers repeating in DEVICE SELECT I/O space. [@audetto]
|
||||
. [Bug #1110] Fix for WOZ and quarter tracks for A2osX's 192K floppy image.
|
||||
- Support two adjacent phases turned off in rapid sequence.
|
||||
. [Bug #1108] Fix for C3 ROM not set correctly when loading a save-state with a VidHD (in slot 3).
|
||||
. [Bug #1106] Fix for minor screen corruption with VidHD enabled.
|
||||
- Debugger: fix for mouse-click hit-tests with VidHD enabled.
|
||||
. [Bug #1104] Fix for rare Mockingboard speech race condition when debugger-stepping.
|
||||
. [PR #1098] Internal: refactor debugger. [@kiyolee]
|
||||
. Change: Mockingboard's SSI263: support reg3's amplitude (fix for TR speaking during SSI263 detection).
|
||||
. Change: DebuggerAutoRun.txt: extend search path to first try CurrentDir, then ProgramDir.
|
||||
|
||||
|
||||
1.30.10.0 - 27 May 2022
|
||||
-----------------------
|
||||
. [Change #1097] Extend Uthernet II to support DNS offloading. [audetto]
|
||||
- Details: https://github.com/a2retrosystems/uthernet2/wiki/Virtual-W5100-with-DNS
|
||||
- No need for ethernet, so now works with host PC's WiFi.
|
||||
- Supported by @oliverschmidt's A2Stream v1.2.
|
||||
- NB. This virtual DNS is enable by default (but can be disabled via the Config UI).
|
||||
- NB. Real W5100 chips don't offer this!
|
||||
. [Bug #1078] WOZ support: Better LSS support for reading write-protect.
|
||||
- Fix images 'Run For It' and 'Stickybear Town Builder' (both when write-protected).
|
||||
. [PR #1100] Uthernet II fixes for UDP and IPRAW modes. [audetto]
|
||||
. [PR #1084 + others] Internal: refactor debugger. [kiyolee]
|
||||
. Fix Phasor card: use correct primary AY8913 for Phasor-native & MB modes (now checked in mb-audit v1.2).
|
||||
. Command line: add -wav-speaker <file> & -wav-mockingboard <file>
|
||||
- Save a .wav of either Speaker or Mockingboard audio output during the emulation session.
|
||||
- Warning: there's no file size limit, so it just keeps saving until AppleWin exits.
|
||||
|
||||
|
||||
1.30.9.0 - 23 Mar 2022
|
||||
----------------------
|
||||
. [Change #518] Support Uthernet II card in slot 3. [audetto]
|
||||
- EG. Use with Contiki, A2osX, ii-vision, A2Stream etc.
|
||||
- Support for W5100 modes: TCP, UDP, IPRAW and MACRAW (no support for PPPoE mode, interrupts and SPI).
|
||||
. [Bug #1066] Fix for save-states where (eg) disk image name contains '#' character.
|
||||
. [Bug #1017] Fix for printer interface where character got output twice.
|
||||
. [PR #1031 + others] Internal: refactor string output handling. [kiyolee]
|
||||
. Change: default install of AppleWin now sets slot 3 as empty (was Uthernet I card)
|
||||
. Fix 6522 bug: IFR.T2 was always set when counter.b15=1
|
||||
|
||||
|
||||
1.30.8.0 - 8 Feb 2022
|
||||
---------------------
|
||||
. [Bug #1023] WOZ support: Tweak to track sync support.
|
||||
|
@ -15,7 +106,7 @@ Tom Charlesworth
|
|||
- Fixes: What's My Logic, Forbidden Quest, The Isle of Mem.
|
||||
. [Bug #1018] Support AN3 for //e models.
|
||||
. [Bug #1015] Registry: fix support for legacy 'Harddisk Enable' key.
|
||||
. [PR #1028] Internal: Split 6522 out of MB code and into own class (bumps MB version in save-state).
|
||||
. [PR #1028] Internal: Split 6522 out of MB code and into own class (bumps MB version in save-state to v8).
|
||||
. [PR #1025] Load save-state for Cards: improve error messages. [audetto]
|
||||
. [PR #1014] Correct BMP creation. [audetto]
|
||||
. SSC: Fix for command line -dcd not being honoured. (Regression)
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
@COPY /Y "%APPLEWIN_ROOT%\docs\Debugger_Changelog.txt" "%~1"
|
||||
@COPY /Y "%APPLEWIN_ROOT%\help\AppleWin.chm" "%~1"
|
||||
@COPY /Y "%APPLEWIN_ROOT%\Release v141_xp\AppleWin.exe" "%~1"
|
||||
@MKDIR "%~1\snesmax"
|
||||
@COPY /Y "%APPLEWIN_ROOT%\snesmax\*" "%~1\snesmax"
|
||||
CD "%~1"
|
||||
"C:\Program Files (x86)\7-Zip\7z.exe" a ..\AppleWin"%~1".zip *
|
||||
"C:\Program Files (x86)\7-Zip\7z.exe" a ..\AppleWin"%~1"-PDB.zip "%APPLEWIN_ROOT%\Release v141_xp\AppleWin.pdb"
|
||||
|
|
|
@ -2,6 +2,11 @@ Coding Conventions for AppleWin
|
|||
===============================
|
||||
|
||||
History:
|
||||
v6 - 12-Jan-2023 (TC)
|
||||
. Avoid global vars & provide getter/setter accessor functions.
|
||||
. Avoid C++11 empty initializer lists. (PR#634)
|
||||
v5 - 03-Apr-2022 (TC)
|
||||
. #1072: Add a space after keywords.
|
||||
v4 - 05-Mar-2022 (TC)
|
||||
. #1050: Added info about Platform Toolset v141_xp
|
||||
. Use of C++11/14/17
|
||||
|
@ -117,9 +122,21 @@ It is recommended (but not mandatory):
|
|||
. to have/use explicit parenthesis
|
||||
. to have spaces between operators
|
||||
|
||||
Eg:
|
||||
EG:
|
||||
. Prefer: z = ((a + b) + 1) instead of: z=((a+b)+1)
|
||||
|
||||
2.8: Add a space after keywords (if, for, switch, while, etc).
|
||||
|
||||
EG:
|
||||
for (int i=0; i<10; i++)
|
||||
|
||||
Not:
|
||||
for(int i=0; i<10; i++)
|
||||
|
||||
2.9: Avoid global variables.
|
||||
|
||||
If a free variable exists within a C++ file, then declare it static and provide getter & setter accessor functions.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
3) Use of sprintf() etc.
|
||||
|
@ -141,6 +158,13 @@ Use type deduction only if it makes the code clearer to readers who aren't famil
|
|||
or if it makes the code safer. Do not use it merely to avoid the inconvenience of writing an explicit type.
|
||||
(Ref: https://google.github.io/styleguide/cppguide.html#Type_deduction)
|
||||
|
||||
4.2: Avoid C++11 empty initializer lists
|
||||
|
||||
This notation can be too obscure, compared to using regular initialization (for POD) or ctors (for classes).
|
||||
EG, avoid this:
|
||||
int var {};
|
||||
struct s {};
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Appendix: Legacy Hungarian notation
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
/*
|
||||
2.9.1.14 Fix disassembly when in middle of data
|
||||
Example:
|
||||
ASC 7D0:7D7
|
||||
ASC 7D8:7DF
|
||||
7CF:EA 40 41 42 43 44 45 46 47 48
|
||||
U 7D7
|
||||
|
||||
2.9.1.13 Added: CD now detects ".." to change to the previous directory and chops the trailing sub-directory from the current path.
|
||||
It worked before but would clutter up the current directory with a trailing "..\".
|
||||
2.9.1.12 Added: New commands HGR0, HGR3, HGR4, HGR5 to see pseudo pages $00, $60, $80, $A0 respectively.
|
||||
|
@ -35,7 +42,7 @@
|
|||
X 2002:2003
|
||||
Released post 1.30.7.0
|
||||
|
||||
2.9.1.0 Added: Bookmarks now have their own indicator (a number with a box around it) and replace the ":" seperator. Updated Debug_Font.bmp
|
||||
2.9.1.0 Added: Bookmarks now have their own indicator (a number with a box around it) and replace the ":" separator. Updated Debug_Font.bmp
|
||||
|
||||
.18 Fixed: Resetting bookmarks wasn't setting the total bookmarks back to zero.
|
||||
.17 Fixed: If all bookmarks were used then setting a new one wouldn't update an existing one to the new address.
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
Start with a floppy disk in slot 6 drive-2.<br>
|
||||
NB. -s6d2 has the meaning same as -d2.<br><br>
|
||||
-s5d1 <pathname><br>
|
||||
Start with a floppy disk in slot 5 drive-1 (must be used with '-s5 diskii').<br><br>
|
||||
Start with a floppy disk in slot 5 drive-1 (must be used with '-s5 diskii' or '-s5 diskii13').<br><br>
|
||||
-s5d2 <pathname><br>
|
||||
Start with a floppy disk in slot 5 drive-2 (must be used with '-s5 diskii').<br><br>
|
||||
Start with a floppy disk in slot 5 drive-2 (must be used with '-s5 diskii' or '-s5 diskii13').<br><br>
|
||||
-h1 <pathname><br>
|
||||
Start with hard disk 1 plugged-in (and auto power-on the Apple II). NB. Hard disk controller card gets enabled.<br><br>
|
||||
-h2 <pathname><br>
|
||||
|
@ -43,15 +43,23 @@
|
|||
Insert an Apple 16K Language Card into slot 0 in the original Apple II and use the F8 auto-start ROM.<br>
|
||||
NB. The Apple II+ already defaults to having a Language Card, so this switch is not required.<br><br>
|
||||
-s1 empty<br>
|
||||
Remove the printer card from slot 1.<br><br>
|
||||
Remove the parallel printer card from slot 1.<br><br>
|
||||
-s1 parallel<br>
|
||||
Insert a parallel printer card into slot 1.<br><br>
|
||||
-s2 empty<br>
|
||||
Remove the SSC card from slot 2.<br><br>
|
||||
-s2 ssc<br>
|
||||
Insert a SSC into slot 2.<br><br>
|
||||
-s3 empty<br>
|
||||
Remove the Uthernet card from slot 3.<br><br>
|
||||
Remove any card from slot 3.<br><br>
|
||||
-s3 vidhd<br>
|
||||
Insert a VidHD card into slot 3.<br><br>
|
||||
-s5 diskii<br>
|
||||
Insert a 2nd Disk II controller card into slot 5.<br><br>
|
||||
-s6 diskii<br>
|
||||
Insert a Disk II controller card into slot 5 or 6.<br><br>
|
||||
-s5 diskii13<br>
|
||||
-s6 diskii13<br>
|
||||
Insert a Disk II controller card (with 13-sector firmware) into slot 5 or 6.<br><br>
|
||||
-s6 empty<br>
|
||||
Remove the Disk II controller card from slot 6.<br><br>
|
||||
-s7 empty<br>
|
||||
|
@ -78,6 +86,9 @@
|
|||
<li>best: picks the highest resolution where the height is an integer multiple of (192*2)</li>
|
||||
<li>nnnn: select a specific resolution with height=nnnn pixels</li>
|
||||
</ul>
|
||||
-fs-width=<nnnn><br>
|
||||
Use in conjunction with -fs-height to select a better aspect ratio for full-screen mode.<br>
|
||||
EG. for 4:3 aspect ratio on monitors that support it: -no-full-screen -fs-width=1600 -fs-height=1200<br><br>
|
||||
NB. Combine with <em>-no-full-screen</em> to start in Windowed mode. Without this it'll just default to full-screen.<br>
|
||||
NB. When switching to Windowed mode the default desktop resolution will be restored, and when switching back to full-screen mode this better resolution will again be used.<br><br>
|
||||
-rom <file><br>
|
||||
|
@ -156,6 +167,10 @@
|
|||
<li>NB. Both these apple/sl7 cards support an extra foreground/background hi-res mode that can be triggered by AN3 switching, resulting in corrupt color graphics! See <a href="Troubleshooting.html">troubleshooting</a>.
|
||||
</ul>
|
||||
<li><i>eve/feline</i> are Le Chat Mauve variants.</li>
|
||||
<ul>
|
||||
<li>Eve is currently unsupported, so the behavior just defaults to 'apple' RGB card type.
|
||||
<li>Feline differs from 'apple' card type in that it doesn't support the 160 color pixel mode (so falls back to 140 mode) and has a slightly different color palette.
|
||||
</ul>
|
||||
</ul>
|
||||
Use in conjunction with the 'Color (RGB Card/Monitor)' video mode.<br><br>
|
||||
-rgb-card-foreground <n><br>
|
||||
|
@ -175,7 +190,19 @@
|
|||
Force a power-on.<br>
|
||||
Use to auto power-on when not using -d1, -h1 or -load-state.<br><br>
|
||||
-snes-max-alt-joy1 or -snes-max-alt-joy2<br>
|
||||
Use alternate button mappings for the SNES MAX card. See <a href="cfg-input.html">Input Settings</a>.<br>
|
||||
Use alternate button mappings for the SNES MAX card. See <a href="cfg-input.html">Input Settings</a>.<br><br>
|
||||
-snes-max-user-joy1 <file.yaml> or -snes-max-user-joy2 <file.yaml><br>
|
||||
Use a user specified button mappings file for the SNES MAX card.<br>
|
||||
For some examples, see the supplied <i>controller_*.yaml</i> files in the <i>snesmax</i> folder.<br>
|
||||
<br>
|
||||
-wav-speaker <file.wav><br>
|
||||
Save the speaker audio to a .wav file.<br>
|
||||
Warning: there's no file size limit, so it just keeps saving until AppleWin exits (~5MB per minute).<br>
|
||||
<br>
|
||||
Save the Mockingboard audio to a .wav file.<br>
|
||||
-wav-mockingboard <file.wav><br>
|
||||
Warning: there's no file size limit, so it just keeps saving until AppleWin exits (~10MB per minute).<br>
|
||||
<br>
|
||||
|
||||
<br>
|
||||
<P style="FONT-WEIGHT: bold">Debug arguments:
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<hr size="4">
|
||||
<p>The team would like to thank the following people for their contributions:</p>
|
||||
<p style="MARGIN-LEFT: 40px">Brian Broker: This HTML / CHM help file</p>
|
||||
<p style="MARGIN-LEFT: 40px">Thomas Stahl: TV emulation mode (up to v1.25.0.4)</p>
|
||||
<p style="MARGIN-LEFT: 40px">Thomas Stahl: TV emulation mode</p>
|
||||
<p style="MARGIN-LEFT: 40px">Greg Hedger: SSI263 phoneme samples</p>
|
||||
<p style="MARGIN-LEFT: 40px">Robert Hoem: Hard disk card (source module & f/w)</p>
|
||||
<p style="MARGIN-LEFT: 40px">VICE team: TFE, Z80, MC6821 PIA emulation modules (<a href="http://vice-emu.sourceforge.net/index.html#developers">http://vice-emu.sourceforge.net/index.html#developers</a>)<br>
|
||||
|
@ -21,10 +21,12 @@
|
|||
<p style="MARGIN-LEFT: 40px">Bob Sander-Cederlof: Applesoft Symbols (<a href="http://www.txbobsc.com/scsc/scdocumentor/index.html">http://www.txbobsc.com/scsc/scdocumentor/</a> S-C DocuMentor: Applesoft)</p>
|
||||
<p style="MARGIN-LEFT: 40px">David Schmidt: Updates to this help file</p>
|
||||
<p style="MARGIN-LEFT: 40px">Mike Harvey, Founder & Editor of Nibble Magazine: For providing us Apple fans the pleasure of eagerly awaiting each next month's issue to learn about the Apple! (<a href="http://www.nibblemagazine.com/">http://www.nibblemagazine.com/</a>)</p>
|
||||
<p style="MARGIN-LEFT: 40px">Andrea Odetti: working on making the source code more portable</p>
|
||||
<p style="MARGIN-LEFT: 40px">Andrea Odetti: working on making the source code more portable & Uthernet II card support</p>
|
||||
<p style="MARGIN-LEFT: 40px">Iván Izaguirre: Taiwanese Copam Base64A Apple II clone</p>
|
||||
<p style="MARGIN-LEFT: 40px">Arnaud C: debugger suggestions and help with 6502/6522/video timing issues</p>
|
||||
<p style="MARGIN-LEFT: 40px">Cyril Lambin: RGB card/monitor rendering, debugger improvements</p>
|
||||
<p style="MARGIN-LEFT: 40px">Alex Lukacz: 4Play & SNES MAX card support</p>
|
||||
<p style="MARGIN-LEFT: 40px">Matthew D'Asaro: Game I/O Controller copy-protection dongle support</p>
|
||||
<p style="MARGIN-LEFT: 40px">Erik Struiksma: SNES MAX controller mapping files</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"><title>Advanced Settings</title></head>
|
||||
<body style="background-color: rgb(255, 255, 255); font-family: verdana;" alink="#008000" link="#008000" vlink="#008000">
|
||||
<h2 style="color: rgb(0, 128, 0);">Advanced Settings</h2>
|
||||
<hr size="4"><img style="width: 354px; height: 460px; float: right;" src="img/advanced.png" alt="Advanced settings" hspace="5" vspace="5">
|
||||
<p><strong>Save State File Name:</strong><br>
|
||||
<hr size="4"><img style="width: 354px; height: 497px; float: right;" src="img/advanced.png" alt="Advanced settings" hspace="5" vspace="5">
|
||||
|
||||
<p><strong>Save State Filename:</strong><br>
|
||||
This is the file name to use for save-state files. The default
|
||||
directory is the same as where your AppleWin.exe program is stored.</p>
|
||||
<p><strong>Save State on Exit:</strong><br>
|
||||
|
@ -19,18 +20,7 @@ emulation by pressing the F11 key.</p>
|
|||
Press this button to load the specified state file into
|
||||
the emulator. You can also load the system state during
|
||||
emulation by pressing the F12 key.</p>
|
||||
<p><strong>Clone:</strong><br>
|
||||
If you have specified Computer as 'Clone' on the main Configuration
|
||||
page, then this drop-down menu can be used to specify the clone type.<br>
|
||||
NB. Pravets 82, 8M and 8A are Bulgarian Apple II clones;
|
||||
TK3000 is a Brazilian //e clone;
|
||||
Base 64A is a Taiwanese Apple II clone.<br>
|
||||
<ul>
|
||||
<li>Pravets 8A: Use F10 for the Pravets Caps Lock (and the PC's Caps Lock key controls Cyrillic/Latin lock).
|
||||
<li>TK3000: Use Scroll Lock for the 'mode' key. Use to switch between standard Apple II and accented characters.
|
||||
<li>Base 64A: Use Delete for the 'F2' key (eg. press F2, release F2 then press a key to auto-type a BASIC keyword).
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p><strong>Printer settings </strong>(Printer is emulated in slot 1)
|
||||
</p>
|
||||
<p style="margin-left: 40px;"><strong>Printer dump filename:<br>
|
||||
|
@ -67,7 +57,21 @@ disable appending when dumping to a real printer.)
|
|||
</strong>When printing is started, a printer file is created and it is
|
||||
closed either after the specified time expires, or when
|
||||
the emulator is reset. This setting is emulation speed dependent.
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<p><strong>Clone:</strong><br>
|
||||
If you have specified Computer as 'Clone' on the main Configuration
|
||||
page, then this drop-down menu can be used to specify the clone type.<br>
|
||||
NB. Pravets 82, 8M and 8A are Bulgarian Apple II clones;
|
||||
TK3000 is a Brazilian //e clone;
|
||||
Base 64A is a Taiwanese Apple II clone.<br>
|
||||
<ul>
|
||||
<li>Pravets 8A: Use F10 for the Pravets Caps Lock (and the PC's Caps Lock key controls Cyrillic/Latin lock).
|
||||
<li>TK3000: Use Scroll Lock for the 'mode' key. Use to switch between standard Apple II and accented characters.
|
||||
<li>Base 64A: Use Delete for the 'F2' key (eg. press F2, release F2 then press a key to auto-type a BASIC keyword).
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p><strong>The Freeze's non-autostart F8 rom:</strong><br>
|
||||
If you have specified Computer as 'Apple ][' or 'Apple ][+' on the main
|
||||
Configuration page, then you will be able to enable this setting.
|
||||
|
@ -75,4 +79,16 @@ The Freeze F8 rom is a hacker's rom that replaces the normal 2K rom at
|
|||
$F800. <a href="cfg-advanced-freeze-rom.html">Here's the
|
||||
original release note</a>
|
||||
</p>
|
||||
</body></html>
|
||||
|
||||
<p><strong>Game I/O Connector:</strong><br>
|
||||
From the drop-down menu, select a device to use in the internal Game I/O Connector.
|
||||
Supported devices are:
|
||||
<ul>
|
||||
<li> Empty
|
||||
<li> SDS Datakey - SpeedStar (copy protection dongle)
|
||||
</ul>
|
||||
NB. Copy protection dongles can interfere with joysticks (eg. buttons may be hardwired to a fixed state), so only use dongles with the intended software.<br>
|
||||
NB. For Apple II/II+ models, when a joystick is selected (from the <a href="cfg-input.html">Input</a> tab), then there is also an implicit joystick connected at the same time as the device selected here.
|
||||
</p>
|
||||
|
||||
</body></html>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
|
||||
<strong>Ethernet Settings...:</strong><br>
|
||||
This allows to choose which network interface card (NIC) you want to
|
||||
use with the Uthernet card.<br>
|
||||
use with the Uthernet or Uthernet II card.<br>
|
||||
<br>
|
||||
|
||||
<strong>Emulation Speed Control:</strong><br>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</head>
|
||||
<body style="background-color: rgb(255, 255, 255); font-family: verdana;" alink="#008000" link="#008000" vlink="#008000">
|
||||
<h2 style="color: rgb(0, 128, 0);">Disk Settings</h2>
|
||||
<hr size="4"><img style="width: 354px; height: 460px; float: right;" src="img/disk.png" alt="Disk settings" hspace="5" vspace="5">
|
||||
<hr size="4"><img style="width: 354px; height: 497px; float: right;" src="img/disk.png" alt="Disk settings" hspace="5" vspace="5">
|
||||
|
||||
<h3>Floppy Controller Settings:</h3>
|
||||
<p><strong>Enhanced disk access speed:</strong><br>
|
||||
|
@ -19,6 +19,10 @@ properly. This is the speed at which the real hardware
|
|||
would access data from your drives.
|
||||
</p>
|
||||
|
||||
<p><strong>Show status:</strong><br>
|
||||
In 2x windowed-mode, optionally show the Track and Sector values for Drives 1 and 2 (for any Disk II cards in slots 5 and/or 6).
|
||||
Hovering over this status will show a tooltip with both decimal and hexadecimal values, and the track includes the full fractional quarter track value too.
|
||||
|
||||
<p><strong>Disk 1/2 drop-down menus (slot 6):</strong><br>
|
||||
These menus allow you to select floppy disk images to 'insert' into the
|
||||
emulated floppy drives 1 and 2. This can also be done during emulation by <a href="toolbar.html">using the toolbar</a> or using the F3/F4 keys. Diskettes can be swapped by pressing F5 during emulation. You can also eject images from this menu.
|
||||
|
|
|
@ -98,6 +98,14 @@ Default comparison operator is equal
|
|||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BPV vpos[,len]</span></b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">Add Breakpoint trigger when video-scanner's vertical position matches vpos. (NB. Auto-disable when hit.)</span></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BPD</span></b></font></font></p>
|
||||
</td>
|
||||
|
@ -105,7 +113,7 @@ Default comparison operator is equal
|
|||
<p><i><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">Disable Breakpoint (grayed out).</span></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BPE</span></b></font></font></p>
|
||||
</td>
|
||||
|
@ -113,7 +121,7 @@ Default comparison operator is equal
|
|||
<p><i><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">Enable Breakpoint (colored red).</span></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BPC #</span></b></font></font></p>
|
||||
</td>
|
||||
|
@ -122,7 +130,7 @@ Default comparison operator is equal
|
|||
Note: The asterisk ‘*’ may be used to clear all breakpoints.</span></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BPL</span></b></font></font></p>
|
||||
</td>
|
||||
|
@ -130,7 +138,7 @@ Note: The asterisk
|
|||
<p><i><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">List Breakpoints.</span></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BPIO</span></b></font></font></p>
|
||||
</td>
|
||||
|
@ -138,7 +146,7 @@ Note: The asterisk
|
|||
<p><i><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">(In a future version, will add Breakpoint trigger on memory read or write.)</span></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BPP</span></b></font></font></p>
|
||||
</td>
|
||||
|
@ -146,7 +154,7 @@ Note: The asterisk
|
|||
<p><i><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">(In a future version, will add Breakpoint trigger on specific flag cleared or set.)</span></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BRK [0|1|2|3|all] [on|off]</span></b></font></font></p>
|
||||
</td>
|
||||
|
@ -154,7 +162,7 @@ Note: The asterisk
|
|||
<p><i><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">Break on BRK or Invalid 1-3 byte opcodes</span></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BRKOP [opcode]</span></b></font></font></p>
|
||||
</td>
|
||||
|
@ -162,7 +170,7 @@ Note: The asterisk
|
|||
<p><i><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">Break on Opcode</span></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b><span style="BACKGROUND: 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BRKINT [on|off]</span></b></font></font></p>
|
||||
</td>
|
||||
|
@ -399,6 +407,14 @@ Note: The asterisk
|
|||
<p><font color="#ffffff"><i>Add Breakpoint when Stack has had something pushed onto it.</i></font></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#000000">
|
||||
<td bgcolor="#000000" width="25%">
|
||||
<p><font color="#00b8ff"><font face="Courier"><b><span style="BACKGROUND: rgb(0,0,0) 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BPV A0</span></b></font></font></p>
|
||||
</td>
|
||||
<td bgcolor="#000000" width="75%">
|
||||
<p><font color="#ffffff"><i>Add Breakpoint when video-scanner is at line 160 ($A0) which is the start of the MIXED area.</i></font></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#000000">
|
||||
<td bgcolor="#000000" width="25%">
|
||||
<p><font color="#00b8ff"><font face="Courier"><b><span style="BACKGROUND: rgb(0,0,0) 0% 50%; moz-background-clip: initial; moz-background-origin: initial; moz-background-inline-policy: initial">BRK ON</span></b></font></font></p>
|
||||
|
|
|
@ -230,8 +230,10 @@ MODE 2</span></b></font></font></p>
|
|||
You can run custom batch or script files that contain debugger commands.
|
||||
Scripts files do not echo their input; to print a string to the output console
|
||||
window, use the <b>ECHO</b> command. NB. When AppleWin initially starts-up, it
|
||||
will attempt to auto-run '<b>DebuggerAutoRun.txt</b>' (located in the same folder
|
||||
as AppleWin.exe).
|
||||
will attempt to auto-run '<b>DebuggerAutoRun.txt</b>' (searching starts in the "Current Directory"[1], otherwise in the same folder
|
||||
as AppleWin.exe).</br>
|
||||
</br>
|
||||
[1] "Current Directory" is implicitly set when inserting disk/harddisk images and ultimately by the command line switch: -current-dir <path>.
|
||||
</p>
|
||||
<br>
|
||||
<table border="0" cellpadding="2" cellspacing="0" width="80%">
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><font size="4"><b>Examples</b>:</font></p>
|
||||
<p><font size="3"><b>Examples</b>:</font></p>
|
||||
<table bgcolor="#000000" border="0" cellpadding="2" cellspacing="0" width="90%">
|
||||
<COLGROUP>
|
||||
<col width="64">
|
||||
|
@ -151,6 +151,142 @@ FF0A</span></b></font></font></p>
|
|||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<h3>Zero-page Watches</h3>
|
||||
<p>Add a zero-page watch at the indirect address (nn).</p>
|
||||
<table border="0" cellpadding="2" cellspacing="0" width="75%">
|
||||
<COLGROUP>
|
||||
<col width="64">
|
||||
<col width="192">
|
||||
<tbody>
|
||||
<tr bgcolor="#000000">
|
||||
<td bgcolor="#000000" width="25%">
|
||||
<p><font color="#ffffff"><b>Command</b></font></p>
|
||||
</td>
|
||||
<td bgcolor="#000000" width="75%">
|
||||
<p style="FONT-STYLE: normal"><font color="#ffffff"><b>Effect</b></font></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>ZPA (or ZP) nn</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>Add/Update address to next zero page pointer</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>ZPA (or ZP) # nn</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>Add/Update address to specific zero page pointer</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>ZPC #</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>Clear (remove) zero page pointer</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>ZPD #</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>Disable zero page pointer - it is still in the list, just not active</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>ZPE #</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>(Re)Enable disabled zero page pointer</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>ZPL</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>List all zero page pointers</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<h3>Memory Watches</h3>
|
||||
<p>Add a 16-bit memory watch at the 16-bit address nnnn.<br>
|
||||
NB. For 'WA # v': specifying 'v' instead of an address will watch the video scanner.</p>
|
||||
<table border="0" cellpadding="2" cellspacing="0" width="75%">
|
||||
<COLGROUP>
|
||||
<col width="64">
|
||||
<col width="192">
|
||||
<tbody>
|
||||
<tr bgcolor="#000000">
|
||||
<td bgcolor="#000000" width="25%">
|
||||
<p><font color="#ffffff"><b>Command</b></font></p>
|
||||
</td>
|
||||
<td bgcolor="#000000" width="75%">
|
||||
<p style="FONT-STYLE: normal"><font color="#ffffff"><b>Effect</b></font></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>WA (or W) nnnn|symbol</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>Add/Update address or symbol to next watch</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>WA (or W) # nnnn|symbol|v</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>Add/Update address or symbol to specific watch</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>WC #</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>Clear (remove) watch</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>WD #</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>Disable specific watch - it is still in the list, just not active</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#999999">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>WE #</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>(Re)Enable disabled watch</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr bgcolor="#cccccc">
|
||||
<td width="25%">
|
||||
<p><font color="#000000"><font face="Courier"><b>WL</b></font></font></p>
|
||||
</td>
|
||||
<td width="75%">
|
||||
<p><i>List all watches</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<h3><a name="Memory_Search">Searching Memory</a></h3>
|
||||
<p>You can search memory for hex values. Wildcard support is also supported
|
||||
via the '<b>?</b>' wildcard operator, including nibble searching. A
|
||||
|
|
|
@ -83,7 +83,7 @@ Apple II would not last six months.</p>
|
|||
late and
|
||||
suffered from poor backwards compatibility and a nearly 100%
|
||||
hardware failure rate. Although Apple eventually addressed these
|
||||
issues, they were not able overcome the Apple III's bad
|
||||
issues, they were not able to overcome the Apple III's bad
|
||||
reputation. Apple III sales remained poor, while sales of the
|
||||
older Apple II continued to climb. </p>
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 35 KiB |
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 34 KiB |
|
@ -32,7 +32,7 @@
|
|||
<li>Parallel Printer card</li>
|
||||
<li>Super Serial card</li>
|
||||
<li>No-Slot clock</li>
|
||||
<li>Uthernet card</li>
|
||||
<li>Uthernet & Uthernet II cards</li>
|
||||
<li>4Play & SNES MAX joystick cards</li>
|
||||
<li>VidHD card</li>
|
||||
</ul>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
Copyright © 1994-1996, Michael O'Brien<br>
|
||||
Copyright © 2001, Oliver Schmidt<br>
|
||||
Copyright © 2002-2005, Tom Charlesworth<br>
|
||||
Copyright © 2006-2022, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis<br>
|
||||
Copyright © 2006-2023, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis<br>
|
||||
<br>
|
||||
<a href="applewin-team.html">AppleWin team</a>
|
||||
<br>
|
||||
|
@ -31,7 +31,7 @@
|
|||
<li><a href="sound.html">Sound</a>
|
||||
<li><a href="clock.html">Clock</a>
|
||||
<li><a href="card-ssc.html">Super Serial card</a>
|
||||
<li><a href="uthernet.html">Uthernet network card</a>
|
||||
<li><a href="uthernet.html">Uthernet network cards</a>
|
||||
<li><a href="configuration.html">AppleWin Configuration</a>
|
||||
<li><a href="dbg-toc-intro.html">Using the Debugger</a>
|
||||
<li><a href="resources.html">Resources</a></li>
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Uthernet network card</title>
|
||||
<title>Uthernet network cards</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
</head>
|
||||
<body style="FONT-FAMILY: verdana; BACKGROUND-COLOR: rgb(255,255,255)" alink="#008000"
|
||||
link="#008000" vlink="#008000">
|
||||
<h2 style="COLOR: rgb(0,128,0)">Uthernet network card</h2>
|
||||
<h2 style="COLOR: rgb(0,128,0)">Uthernet network cards</h2>
|
||||
<hr size="4">
|
||||
<p style="FONT-WEIGHT: bold">Overview:
|
||||
</p>
|
||||
<P>The Uthernet network card coupled with the Contiki OS allows you to browse the
|
||||
<P>The Uthernet network cards coupled with the Contiki OS allow you to browse the
|
||||
internet on your Apple.</P>
|
||||
<P style="FONT-WEIGHT: bold">Acknowledgment:
|
||||
</P>
|
||||
<P>Uthernet (TFE) support in Applewin was made possible by implementing the GPL
|
||||
<P>Uthernet (TFE) support in AppleWin was made possible by implementing the GPL
|
||||
source written by Spiro Trikaliotis for the Vice emulator - <A href="http://vice-emu.sourceforge.net/index.html#developers">
|
||||
http://vice-emu.sourceforge.net/index.html#developers</A></P>
|
||||
<P><A href="https://a2retrosystems.com/">Uthernet II</A> support in AppleWin has been contributed by Andrea (audetto) Odetti.</P>
|
||||
<P style="FONT-WEIGHT: bold">Details:
|
||||
</P>
|
||||
<P>To enable ethernet support in AppleWin you must first download and install
|
||||
|
@ -35,15 +36,15 @@
|
|||
<P>After AppleWin starts, select the settings icon and then select the ethernet
|
||||
settings button.
|
||||
</P>
|
||||
<P>Uthernet will be disabled. Select Uthernet from the list of available ethernet
|
||||
emulations (currently the only one).
|
||||
<P>Uthernet will be disabled. Select Uthernet or Uthernet II from the list of available ethernet
|
||||
emulations.
|
||||
</P>
|
||||
<P>Select the ethernet interface you want to work with. This must be a physical
|
||||
ethernet interface.
|
||||
</P>
|
||||
<P>If you have more than one interface you may need to select them in turn in order
|
||||
to get the text description for each interface vs what Npcap likes to use for
|
||||
a reference. Select Ok. and then close AppleWin.
|
||||
a reference.
|
||||
</P>
|
||||
<P><span style="font-weight: bold;">Note:</span> Wireless does not work
|
||||
with WinPcap (but see <A href="uthernet-wifi-workaround.html">WiFi Workaround</A>).
|
||||
|
@ -56,7 +57,7 @@
|
|||
also grab a copy of the Uthernet/Contiki getting started guide <A href="http://www.a2retrosystems.com/a2UtherManual.pdf">
|
||||
http://www.a2retrosystems.com/a2UtherManual.pdf</A>
|
||||
</P>
|
||||
<P>When you run AppleWin again, select the contiki80pri.dsk image. Boot AppleWin.
|
||||
<P>Select the contiki80pri.dsk image. Boot AppleWin.
|
||||
</P>
|
||||
<P>Once Contiki is loaded then press Enter to clear the welcome screen and press
|
||||
ESC for a menu.
|
||||
|
@ -87,5 +88,17 @@
|
|||
if you are still having difficulty then you should refer to the VICE network
|
||||
support page for additional information - <A href="http://vicekb.trikaliotis.net/13-005.shtml">
|
||||
http://vicekb.trikaliotis.net/13-005.shtml</A></P>
|
||||
</body>
|
||||
<P style="FONT-WEIGHT: bold">Uthernet II:
|
||||
</P>
|
||||
<P>Most features of the Uthernet II are emulated, with the following caveats:
|
||||
<ul>
|
||||
<li>PPPoE, interrupts and SPI are not implemented</li>
|
||||
<li>server side is not well tested</li>
|
||||
<li>after loading a save-state file, TCP and UDP sockets are closed</li>
|
||||
</ul>
|
||||
</P>
|
||||
<P>The card implements a <A href="https://github.com/a2retrosystems/uthernet2/wiki/Virtual-W5100-with-DNS">Virtual DNS</A>
|
||||
interface (not found on real hardware) for Apple II software to run without raw sockets:
|
||||
this allows operation on any type of network.</P>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -180,14 +180,15 @@ CAPTION "Disk"
|
|||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
GROUPBOX "Floppy Disk Drives",IDC_STATIC,5,7,200,125
|
||||
CONTROL "&Enhanced disk access speed (all drives)",IDC_ENHANCE_DISK_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,19,150,10
|
||||
CONTROL "&Enhanced disk access speed (all drives)",IDC_ENHANCE_DISK_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,19,135,10
|
||||
CONTROL "Show status",IDC_DISKII_STATUS_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,19,50,10
|
||||
|
||||
LTEXT "Disk 1:",IDC_STATIC,10,36,23,8
|
||||
LTEXT "Disk 2:",IDC_STATIC,10,53,23,8
|
||||
COMBOBOX IDC_COMBO_DISK1,40,35,150,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_COMBO_DISK2,40,52,150,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
CONTROL "Enable &Disk II controller in slot 5",IDC_DISKII_SLOT5_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,76,122,10
|
||||
CONTROL "Enable &Disk II controller in slot 5",IDC_DISKII_SLOT5_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,76,115,10
|
||||
LTEXT "Disk 1:",IDC_STATIC,11,93,23,8
|
||||
LTEXT "Disk 2:",IDC_STATIC,11,110,23,8
|
||||
COMBOBOX IDC_COMBO_DISK1_SLOT5,40,92,150,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
|
@ -206,19 +207,22 @@ BEGIN
|
|||
PUSHBUTTON "&Browse...",IDC_CIDERPRESS_BROWSE,161,202,50,14
|
||||
END
|
||||
|
||||
IDD_TFE_SETTINGS_DIALOG DIALOGEX 0, 0, 270, 100
|
||||
IDD_TFE_SETTINGS_DIALOG DIALOGEX 0, 0, 271, 155
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Ethernet Settings"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Ethernet",IDC_TFE_SETTINGS_ENABLE_T,9,7,30,8
|
||||
COMBOBOX IDC_TFE_SETTINGS_ENABLE,45,5,60,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Virtual DNS",IDC_CHECK_TFE_VIRTUAL_DNS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,7,50,8
|
||||
LTEXT "Interface",IDC_TFE_SETTINGS_INTERFACE_T,9,24,30,8
|
||||
COMBOBOX IDC_TFE_SETTINGS_INTERFACE,45,22,210,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "",IDC_TFE_SETTINGS_INTERFACE_NAME,9,44,250,8
|
||||
LTEXT "",IDC_TFE_SETTINGS_INTERFACE_DESC,9,60,250,8
|
||||
DEFPUSHBUTTON "Ok",IDOK,20,75,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,80,75,50,14
|
||||
GROUPBOX "Npcap",IDC_STATIC,5,75,260,55
|
||||
LTEXT "",IDC_TFE_NPCAP_INFO,12,86,240,36
|
||||
DEFPUSHBUTTON "Ok",IDOK,20,135,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,80,135,50,14
|
||||
END
|
||||
|
||||
IDD_PROPPAGE_ADVANCED DIALOGEX 0, 0, 210, 217
|
||||
|
@ -251,7 +255,9 @@ BEGIN
|
|||
LTEXT "&Clone:",IDC_STATIC,5,187,40,8
|
||||
COMBOBOX IDC_CLONETYPE,35,185,100,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "The Free&ze's non-autostart F8 rom (Apple ][ or ][+ only)",IDC_THE_FREEZES_F8_ROM_FW,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,201,194,10
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,201,194,10
|
||||
LTEXT "&Game I/O Connector:",IDC_STATIC,5,220,82,8
|
||||
COMBOBOX IDC_COMBO_GAME_IO_CONNECTOR,89,218,100,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
|
||||
|
@ -292,7 +298,7 @@ BEGIN
|
|||
VALUE "FileDescription", "Apple //e Emulator for Windows"
|
||||
VALUE "FileVersion", APPLEWIN_VERSION_STR
|
||||
VALUE "InternalName", "APPLEWIN"
|
||||
VALUE "LegalCopyright", " 1994-2021 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis"
|
||||
VALUE "LegalCopyright", " 1994-2023 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis"
|
||||
VALUE "OriginalFilename", "APPLEWIN.EXE"
|
||||
VALUE "ProductName", "Apple //e Emulator"
|
||||
VALUE "ProductVersion", APPLEWIN_VERSION_STR
|
||||
|
|
|
@ -61,7 +61,8 @@
|
|||
#define IDC_MB_VOLUME 1010
|
||||
#define IDC_SAVESTATE_BROWSE 1011
|
||||
#define IDC_MONOCOLOR 1012
|
||||
#define IDC_DISKII_SLOT5_ENABLE 1020
|
||||
#define IDC_DISKII_SLOT5_ENABLE 1019
|
||||
#define IDC_DISKII_STATUS_ENABLE 1020
|
||||
#define IDC_HDD_ENABLE 1021
|
||||
#define IDC_HDD_SWAP 1022
|
||||
#define IDC_PASTE_FROM_CLIPBOARD 1023
|
||||
|
@ -119,6 +120,9 @@
|
|||
#define IDC_FOURPLAY_CONFIG 1087
|
||||
#define IDC_SNESMAX_CONFIG 1088
|
||||
#define IDC_CHECK_VIDHD_IN_SLOT3 1089
|
||||
#define IDC_CHECK_TFE_VIRTUAL_DNS 1090
|
||||
#define IDC_TFE_NPCAP_INFO 1091
|
||||
#define IDC_COMBO_GAME_IO_CONNECTOR 1092
|
||||
#define IDM_EXIT 40001
|
||||
#define IDM_HELP 40002
|
||||
#define IDM_ABOUT 40003
|
||||
|
@ -134,7 +138,7 @@
|
|||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 149
|
||||
#define _APS_NEXT_COMMAND_VALUE 40012
|
||||
#define _APS_NEXT_CONTROL_VALUE 1082
|
||||
#define _APS_NEXT_CONTROL_VALUE 1083
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define APPLEWIN_VERSION 1,30,8,0
|
||||
#define APPLEWIN_VERSION 1,30,13,0
|
||||
|
||||
#define xstr(a) str(a)
|
||||
#define str(a) #a
|
||||
|
|
21
snesmax/controller_Chinese_DualPS2adapter.yaml
Normal file
21
snesmax/controller_Chinese_DualPS2adapter.yaml
Normal file
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
File_hdr:
|
||||
Tag: AppleWin Controller Button Remapping
|
||||
Version: 1
|
||||
|
||||
Unit:
|
||||
HID: VID_0810&PID_0001
|
||||
Description: Chinese PS2 USB Dual Controller adapter # Description to be used in AppleWin's GUI
|
||||
1: X # triangle
|
||||
2: A # circle
|
||||
3: B # x
|
||||
4: Y # square
|
||||
5: "" # L2
|
||||
6: "" # R2
|
||||
7: LB # L1
|
||||
8: RB # R1
|
||||
9: SELECT # Select
|
||||
10: START # Start
|
||||
11: "" # X/Y Axis button
|
||||
12: "" # Z Axis/Rotation button
|
||||
...
|
25
snesmax/controller_Lik-Sang_SuperSmartjoy.yaml
Normal file
25
snesmax/controller_Lik-Sang_SuperSmartjoy.yaml
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
File_hdr:
|
||||
Tag: AppleWin Controller Button Remapping
|
||||
Version: 1
|
||||
|
||||
Unit:
|
||||
HID: VID_6666&PID_0667
|
||||
Description: Lik-Sang Super Smartjoy adapter # Description to be used in AppleWin's GUI
|
||||
1: X # mirrors to 10 & Z-Rot up
|
||||
2: A # mirrors to 5 & Z-Axis right
|
||||
3: B # mirrors to 6 & Z-Rot down
|
||||
4: Y # mirrors to 11 & Z-Axis left
|
||||
5: "" # A (dup)
|
||||
6: "" # B (dup)
|
||||
7: LB
|
||||
8: RB
|
||||
9: SELECT
|
||||
10: "" # X (dup)
|
||||
11: "" # Y (dup)
|
||||
12: START
|
||||
13: "" # mirrors to X-Axis up
|
||||
14: "" # mirrors to Y-Axis right
|
||||
15: "" # mirrors to X-Axis down
|
||||
16: "" # mirrors to Y-Axis left
|
||||
...
|
19
snesmax/controller_Logitech_F310.yaml
Normal file
19
snesmax/controller_Logitech_F310.yaml
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
File_hdr:
|
||||
Tag: AppleWin Controller Button Remapping
|
||||
Version: 1
|
||||
|
||||
Unit:
|
||||
HID: VID_046D&PID_C21D
|
||||
Description: Logitech F310 # Description to be used in AppleWin's GUI
|
||||
1: B # A
|
||||
2: A # B
|
||||
3: Y # X
|
||||
4: X # Y
|
||||
5: LB # LB
|
||||
6: RB # RB
|
||||
7: SELECT # BACK
|
||||
8: START # START
|
||||
9: "" # X/Y Axis button
|
||||
10: "" # Z Axis/Rotation button
|
||||
...
|
21
snesmax/controller_Raphnet_DualNES_V2.yaml
Normal file
21
snesmax/controller_Raphnet_DualNES_V2.yaml
Normal file
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
File_hdr:
|
||||
Tag: AppleWin Controller Button Remapping
|
||||
Version: 1
|
||||
|
||||
Unit:
|
||||
HID: VID_289B&PID_0042
|
||||
Description: Raphnet Dual NES adapter V2 # Description to be used in AppleWin's GUI
|
||||
1: Y # SNES Y = NES B
|
||||
2: B # SNES B = NES A
|
||||
3: SELECT
|
||||
4: START
|
||||
5: "" # n/a : SNES A
|
||||
6: "" # n/a : SNES X
|
||||
7: "" # n/a : SNES LB
|
||||
8: "" # n/a : SNES RB
|
||||
9: ""
|
||||
10: ""
|
||||
11: ""
|
||||
12: ""
|
||||
...
|
21
snesmax/controller_Raphnet_DualSNES_V2.yaml
Normal file
21
snesmax/controller_Raphnet_DualSNES_V2.yaml
Normal file
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
File_hdr:
|
||||
Tag: AppleWin Controller Button Remapping
|
||||
Version: 1
|
||||
|
||||
Unit:
|
||||
HID: VID_289B&PID_0057
|
||||
Description: Raphnet Dual SNES adapter V2 # Description to be used in AppleWin's GUI
|
||||
1: Y
|
||||
2: B
|
||||
3: SELECT
|
||||
4: START
|
||||
5: A
|
||||
6: X
|
||||
7: LB
|
||||
8: RB
|
||||
9: ""
|
||||
10: ""
|
||||
11: ""
|
||||
12: ""
|
||||
...
|
21
snesmax/controller_Saitek_P2500.yaml
Normal file
21
snesmax/controller_Saitek_P2500.yaml
Normal file
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
File_hdr:
|
||||
Tag: AppleWin Controller Button Remapping
|
||||
Version: 1
|
||||
|
||||
Unit:
|
||||
HID: VID_06A3&PID_FF0C
|
||||
Description: Saitek P2500 Cyborg Force Rumble Pad # Description to be used in AppleWin's GUI
|
||||
1: Y # upper-left
|
||||
2: X # upper-center
|
||||
3: B # lower-left
|
||||
4: A # lower-center
|
||||
5: LB # upper-right
|
||||
6: RB # lower-right
|
||||
7: LB # LB
|
||||
8: RB # RB
|
||||
9: SELECT # button for X/Y Axis {analog left }
|
||||
10: START # button for Z Axis/Rotation {analog right} | AKA Rudder/Throttle
|
||||
11: START # S (FPS)
|
||||
12: SELECT # Digital
|
||||
...
|
23
snesmax/controller_Saitek_P2900.yaml
Normal file
23
snesmax/controller_Saitek_P2900.yaml
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
File_hdr:
|
||||
Tag: AppleWin Controller Button Remapping
|
||||
Version: 1
|
||||
|
||||
Unit:
|
||||
HID: VID_06A3&PID_040C
|
||||
Description: Saitek P2900 Wireless Pad # Description to be used in AppleWin's GUI
|
||||
1: Y # upper-left
|
||||
2: B # lower-left
|
||||
3: A # lower-center
|
||||
4: X # upper-center
|
||||
5: LB # L1
|
||||
6: RB # R1
|
||||
7: SELECT # L2
|
||||
8: START # R2
|
||||
9: RB # lower-right (black)
|
||||
10: LB # upper-right (grey)
|
||||
11: SELECT # button for X/Y Axis {analog left }
|
||||
12: START # button for Z Axis/Rotation {analog right}
|
||||
13: "" # FPS {AppleWin does not read}
|
||||
14: "" # analog "
|
||||
...
|
23
snesmax/controller_Saitek_P990.yaml
Normal file
23
snesmax/controller_Saitek_P990.yaml
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
File_hdr:
|
||||
Tag: AppleWin Controller Button Remapping
|
||||
Version: 1
|
||||
|
||||
Unit:
|
||||
HID: VID_06A3&PID_040B
|
||||
Description: Saitek P990 Dual Analog Pad # Description to be used in AppleWin's GUI
|
||||
1: Y # upper-left
|
||||
2: B # lower-left
|
||||
3: A # lower-center
|
||||
4: X # upper-center
|
||||
5: LB # L1
|
||||
6: RB # R1
|
||||
7: SELECT # L2
|
||||
8: START # R2
|
||||
9: RB # lower-right (black)
|
||||
10: LB # upper-right (grey)
|
||||
11: SELECT # button for X/Y Axis {analog left }
|
||||
12: START # button for Z Axis/Rotation {analog right}
|
||||
13: "" # FPS {AppleWin does not read}
|
||||
14: "" # analog "
|
||||
...
|
21
snesmax/controller_Sony_DualShock4.yaml
Normal file
21
snesmax/controller_Sony_DualShock4.yaml
Normal file
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
File_hdr:
|
||||
Tag: AppleWin Controller Button Remapping
|
||||
Version: 1
|
||||
|
||||
Unit:
|
||||
HID: VID_054C&PID_05C4
|
||||
Description: Sony DualShock 4 # Description to be used in AppleWin's GUI
|
||||
1: Y
|
||||
2: B
|
||||
3: A
|
||||
4: X
|
||||
5: LB
|
||||
6: RB
|
||||
7: ""
|
||||
8: ""
|
||||
9: SELECT
|
||||
10: START
|
||||
11: ""
|
||||
12: ""
|
||||
...
|
|
@ -388,7 +388,9 @@ static __forceinline bool NMI(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn,
|
|||
PUSH(regs.pc & 0xFF)
|
||||
EF_TO_AF
|
||||
PUSH(regs.ps & ~AF_BREAK)
|
||||
regs.ps = regs.ps | AF_INTERRUPT & ~AF_DECIMAL;
|
||||
regs.ps |= AF_INTERRUPT;
|
||||
if (GetMainCpu() == CPU_65C02) // GH#1099
|
||||
regs.ps &= ~AF_DECIMAL;
|
||||
regs.pc = * (WORD*) (mem+0xFFFA);
|
||||
UINT uExtraCycles = 0; // Needed for CYC(a) macro
|
||||
CYC(7);
|
||||
|
@ -431,7 +433,9 @@ static __forceinline bool IRQ(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn,
|
|||
PUSH(regs.pc & 0xFF)
|
||||
EF_TO_AF
|
||||
PUSH(regs.ps & ~AF_BREAK)
|
||||
regs.ps = (regs.ps | AF_INTERRUPT) & (~AF_DECIMAL);
|
||||
regs.ps |= AF_INTERRUPT;
|
||||
if (GetMainCpu() == CPU_65C02) // GH#1099
|
||||
regs.ps &= ~AF_DECIMAL;
|
||||
regs.pc = * (WORD*) (mem+0xFFFE);
|
||||
UINT uExtraCycles = 0; // Needed for CYC(a) macro
|
||||
CYC(7);
|
||||
|
@ -681,7 +685,9 @@ void CpuReset()
|
|||
_ASSERT(mem != NULL);
|
||||
|
||||
// 7 cycles
|
||||
regs.ps = (regs.ps | AF_INTERRUPT) & ~AF_DECIMAL;
|
||||
regs.ps |= AF_INTERRUPT;
|
||||
if (GetMainCpu() == CPU_65C02) // GH#1099
|
||||
regs.ps &= ~AF_DECIMAL;
|
||||
regs.pc = *(WORD*)(mem + 0xFFFC);
|
||||
regs.sp = 0x0100 | ((regs.sp - 3) & 0xFF);
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ static DWORD Cpu6502(DWORD uTotalCycles, const bool bVideoUpdate)
|
|||
switch (iOpcode)
|
||||
{
|
||||
// TODO-MP Optimization Note: ?? Move CYC(#) to array ??
|
||||
case 0x00: BRK CYC(7) break;
|
||||
case 0x00: BRKn CYC(7) break;
|
||||
case 0x01: idx ORA CYC(6) break;
|
||||
case 0x02: HLT CYC(2) break; // invalid
|
||||
case 0x03: idx ASO CYC(8) break; // invalid
|
||||
|
|
|
@ -62,7 +62,7 @@ static DWORD Cpu65C02(DWORD uTotalCycles, const bool bVideoUpdate)
|
|||
switch (iOpcode)
|
||||
{
|
||||
// TODO-MP Optimization Note: ?? Move CYC(#) to array ??
|
||||
case 0x00: BRK CYC(7) break;
|
||||
case 0x00: BRKc CYC(7) break;
|
||||
case 0x01: idx ORA CYC(6) break;
|
||||
case 0x02: IMM NOP CYC(2) break; // invalid
|
||||
case 0x03: NOP CYC(1) break; // invalid
|
||||
|
|
|
@ -56,7 +56,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#undef BNE
|
||||
#undef BPL
|
||||
#undef BRA
|
||||
#undef BRK
|
||||
#undef BRK_NMOS
|
||||
#undef BRK_CMOS
|
||||
#undef BVC
|
||||
#undef BVS
|
||||
#undef CLC
|
||||
|
@ -137,6 +138,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#undef ADCn
|
||||
#undef ASLn
|
||||
#undef BRKn
|
||||
#undef LSRn
|
||||
#undef ROLn
|
||||
#undef RORn
|
||||
|
@ -144,6 +146,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#define ADCn ADC_NMOS
|
||||
#define ASLn ASL_NMOS
|
||||
#define BRKn BRK_NMOS
|
||||
#define LSRn LSR_NMOS
|
||||
#define ROLn ROL_NMOS
|
||||
#define RORn ROR_NMOS
|
||||
|
@ -153,6 +156,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#undef ADCc
|
||||
#undef ASLc
|
||||
#undef BRKC
|
||||
#undef LSRc
|
||||
#undef ROLc
|
||||
#undef RORc
|
||||
|
@ -160,6 +164,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#define ADCc ADC_CMOS
|
||||
#define ASLc ASL_CMOS
|
||||
#define BRKc BRK_CMOS
|
||||
#define LSRc LSR_CMOS
|
||||
#define ROLc ROL_CMOS
|
||||
#define RORc ROR_CMOS
|
||||
|
@ -303,13 +308,21 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#define BNE if (!flagz) BRANCH_TAKEN;
|
||||
#define BPL if (!flagn) BRANCH_TAKEN;
|
||||
#define BRA BRANCH_TAKEN;
|
||||
#define BRK regs.pc++; \
|
||||
#define BRK_NMOS regs.pc++; \
|
||||
PUSH(regs.pc >> 8) \
|
||||
PUSH(regs.pc & 0xFF) \
|
||||
EF_TO_AF \
|
||||
PUSH(regs.ps); \
|
||||
regs.ps |= AF_INTERRUPT; \
|
||||
regs.pc = *(LPWORD)(mem+0xFFFE);
|
||||
#define BRK_CMOS regs.pc++; \
|
||||
PUSH(regs.pc >> 8) \
|
||||
PUSH(regs.pc & 0xFF) \
|
||||
EF_TO_AF \
|
||||
PUSH(regs.ps); \
|
||||
regs.ps |= AF_INTERRUPT; \
|
||||
regs.ps &= ~AF_DECIMAL; /*CMOS clears D flag*/ \
|
||||
regs.pc = *(LPWORD)(mem+0xFFFE);
|
||||
#define BVC if (!flagv) BRANCH_TAKEN;
|
||||
#define BVS if ( flagv) BRANCH_TAKEN;
|
||||
#define CLC flagc = 0;
|
||||
|
|
|
@ -69,9 +69,6 @@ void DummyCard::InitializeIO(LPBYTE pCxRomPeripheral)
|
|||
{
|
||||
switch (QueryType())
|
||||
{
|
||||
case CT_GenericPrinter:
|
||||
PrintLoadRom(pCxRomPeripheral, m_slot);
|
||||
break;
|
||||
case CT_GenericClock:
|
||||
break; // nothing to do
|
||||
case CT_Z80:
|
||||
|
@ -86,11 +83,6 @@ void DummyCard::Update(const ULONG nExecutedCycles)
|
|||
{
|
||||
switch (QueryType())
|
||||
{
|
||||
case CT_GenericPrinter:
|
||||
PrintUpdate(nExecutedCycles);
|
||||
break;
|
||||
case CT_GenericClock:
|
||||
break; // nothing to do
|
||||
case CT_Z80:
|
||||
break; // nothing to do
|
||||
default:
|
||||
|
@ -103,9 +95,6 @@ void DummyCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
|||
{
|
||||
switch (QueryType())
|
||||
{
|
||||
case CT_GenericPrinter:
|
||||
Printer_SaveSnapshot(yamlSaveHelper, m_slot);
|
||||
break;
|
||||
case CT_Z80:
|
||||
Z80_SaveSnapshot(yamlSaveHelper, m_slot);
|
||||
default:
|
||||
|
@ -118,8 +107,6 @@ bool DummyCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||
{
|
||||
switch (QueryType())
|
||||
{
|
||||
case CT_GenericPrinter:
|
||||
return Printer_LoadSnapshot(yamlLoadHelper, m_slot, version);
|
||||
case CT_Z80:
|
||||
return Z80_LoadSnapshot(yamlLoadHelper, m_slot, version);
|
||||
default:
|
||||
|
@ -150,7 +137,7 @@ std::string Card::GetCardName(const SS_CARDTYPE cardType)
|
|||
case CT_MockingboardC:
|
||||
return MockingboardCard::GetSnapshotCardName();
|
||||
case CT_GenericPrinter:
|
||||
return Printer_GetSnapshotCardName();
|
||||
return ParallelPrinterCard::GetSnapshotCardName();
|
||||
case CT_GenericHDD:
|
||||
return HarddiskInterfaceCard::GetSnapshotCardName();
|
||||
case CT_GenericClock:
|
||||
|
@ -182,7 +169,7 @@ std::string Card::GetCardName(const SS_CARDTYPE cardType)
|
|||
|
||||
SS_CARDTYPE Card::GetCardType(const std::string & card)
|
||||
{
|
||||
if (card == Printer_GetSnapshotCardName())
|
||||
if (card == ParallelPrinterCard::GetSnapshotCardName())
|
||||
{
|
||||
return CT_GenericPrinter;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ enum SS_CARDTYPE
|
|||
CT_Uthernet2,
|
||||
};
|
||||
|
||||
enum SLOTS { SLOT0=0, SLOT1, SLOT2, SLOT3, SLOT4, SLOT5, SLOT6, SLOT7, NUM_SLOTS, SLOT_AUX };
|
||||
enum SLOTS { SLOT0=0, SLOT1, SLOT2, SLOT3, SLOT4, SLOT5, SLOT6, SLOT7, NUM_SLOTS, SLOT_AUX, GAME_IO_CONNECTOR };
|
||||
|
||||
class YamlSaveHelper;
|
||||
class YamlLoadHelper;
|
||||
|
|
|
@ -38,6 +38,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "Harddisk.h"
|
||||
#include "Mockingboard.h"
|
||||
#include "MouseInterface.h"
|
||||
#include "ParallelPrinter.h"
|
||||
#include "SAM.h"
|
||||
#include "SerialComms.h"
|
||||
#include "SNESMAX.h"
|
||||
|
@ -68,7 +69,9 @@ void CardManager::InsertInternal(UINT slot, SS_CARDTYPE type)
|
|||
m_slot[slot] = new MockingboardCard(slot, type);
|
||||
break;
|
||||
case CT_GenericPrinter:
|
||||
m_slot[slot] = new DummyCard(type, slot);
|
||||
_ASSERT(m_pParallelPrinterCard == NULL);
|
||||
if (m_pParallelPrinterCard) break; // Only support one Printer card
|
||||
m_slot[slot] = m_pParallelPrinterCard = new ParallelPrinterCard(slot);
|
||||
break;
|
||||
case CT_GenericHDD:
|
||||
m_slot[slot] = new HarddiskInterfaceCard(slot);
|
||||
|
@ -154,6 +157,9 @@ void CardManager::RemoveInternal(UINT slot)
|
|||
case CT_SSC:
|
||||
m_pSSC = NULL;
|
||||
break;
|
||||
case CT_GenericPrinter:
|
||||
m_pParallelPrinterCard = NULL;
|
||||
break;
|
||||
case CT_LanguageCard:
|
||||
case CT_Saturn128K:
|
||||
case CT_LanguageCardIIe:
|
||||
|
@ -161,6 +167,7 @@ void CardManager::RemoveInternal(UINT slot)
|
|||
break;
|
||||
}
|
||||
|
||||
UnregisterIoHandler(slot);
|
||||
delete m_slot[slot];
|
||||
m_slot[slot] = NULL;
|
||||
}
|
||||
|
|
|
@ -11,12 +11,13 @@ public:
|
|||
CardManager(void) :
|
||||
m_pMouseCard(NULL),
|
||||
m_pSSC(NULL),
|
||||
m_pLanguageCard(NULL)
|
||||
m_pLanguageCard(NULL),
|
||||
m_pParallelPrinterCard(NULL)
|
||||
{
|
||||
InsertInternal(SLOT0, CT_Empty);
|
||||
InsertInternal(SLOT1, CT_GenericPrinter);
|
||||
InsertInternal(SLOT2, CT_SSC);
|
||||
InsertInternal(SLOT3, CT_Uthernet);
|
||||
InsertInternal(SLOT3, CT_Empty);
|
||||
InsertInternal(SLOT4, CT_Empty);
|
||||
InsertInternal(SLOT5, CT_Empty);
|
||||
InsertInternal(SLOT6, CT_Disk2);
|
||||
|
@ -56,6 +57,8 @@ public:
|
|||
bool IsMouseCardInstalled(void) { return m_pMouseCard != NULL; }
|
||||
class CSuperSerialCard* GetSSC(void) { return m_pSSC; }
|
||||
bool IsSSCInstalled(void) { return m_pSSC != NULL; }
|
||||
class ParallelPrinterCard* GetParallelPrinterCard(void) { return m_pParallelPrinterCard; }
|
||||
bool IsParallelPrinterCardInstalled(void) { return m_pParallelPrinterCard != NULL; }
|
||||
|
||||
class LanguageCardUnit* GetLanguageCard(void) { return m_pLanguageCard; }
|
||||
|
||||
|
@ -78,4 +81,5 @@ private:
|
|||
class CMouseInterface* m_pMouseCard;
|
||||
class CSuperSerialCard* m_pSSC;
|
||||
class LanguageCardUnit* m_pLanguageCard;
|
||||
class ParallelPrinterCard* m_pParallelPrinterCard;
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "Keyboard.h"
|
||||
#include "Joystick.h"
|
||||
#include "SoundCore.h"
|
||||
#include "SNESMAX.h"
|
||||
#include "ParallelPrinter.h"
|
||||
#include "Interface.h"
|
||||
|
||||
|
@ -48,6 +49,7 @@ bool g_bHookSystemKey = true;
|
|||
bool g_bHookAltTab = false;
|
||||
bool g_bHookAltGrControl = false;
|
||||
|
||||
|
||||
static LPSTR GetCurrArg(LPSTR lpCmdLine)
|
||||
{
|
||||
if (*lpCmdLine == '\"')
|
||||
|
@ -167,6 +169,25 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
|
|||
g_cmdLine.bSlotEmpty[slot] = true;
|
||||
if (strcmp(lpCmdLine, "diskii") == 0)
|
||||
g_cmdLine.slotInsert[slot] = CT_Disk2;
|
||||
if (strcmp(lpCmdLine, "diskii13") == 0)
|
||||
{
|
||||
g_cmdLine.slotInsert[slot] = CT_Disk2;
|
||||
g_cmdLine.slotInfo[slot].isDiskII13 = true;
|
||||
}
|
||||
if (strcmp(lpCmdLine, "parallel") == 0)
|
||||
{
|
||||
if (slot == SLOT1)
|
||||
g_cmdLine.slotInsert[slot] = CT_GenericPrinter;
|
||||
else
|
||||
LogFileOutput("Parallel Printer card currently only supported in slot 1\n");
|
||||
}
|
||||
if (strcmp(lpCmdLine, "ssc") == 0)
|
||||
{
|
||||
if (slot == SLOT2)
|
||||
g_cmdLine.slotInsert[slot] = CT_SSC;
|
||||
else
|
||||
LogFileOutput("SSC currently only supported in slot 2\n");
|
||||
}
|
||||
if (strcmp(lpCmdLine, "vidhd") == 0)
|
||||
{
|
||||
if (slot == SLOT3)
|
||||
|
@ -394,7 +415,7 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
|
|||
}
|
||||
else if (strcmp(lpCmdLine, "-use-real-printer") == 0) // Enable control in Advanced config to allow dumping to a real printer
|
||||
{
|
||||
g_bEnableDumpToRealPrinter = true;
|
||||
g_cmdLine.enableDumpToRealPrinter = true;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-speech") == 0)
|
||||
{
|
||||
|
@ -530,6 +551,36 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
|
|||
{
|
||||
g_cmdLine.snesMaxAltControllerType[1] = true;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-snes-max-user-joy1") == 0 || strcmp(lpCmdLine, "-snes-max-user-joy2") == 0)
|
||||
{
|
||||
const unsigned int joyNum = (strcmp(lpCmdLine, "-snes-max-user-joy1") == 0) ? 0 : 1;
|
||||
|
||||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
lpNextArg = GetNextArg(lpNextArg);
|
||||
|
||||
std::string errorMsg;
|
||||
if (!SNESMAXCard::ParseControllerMappingFile(joyNum, lpCmdLine, errorMsg))
|
||||
{
|
||||
LogFileOutput("%s", errorMsg.c_str());
|
||||
GetFrame().FrameMessageBox(errorMsg.c_str(), TEXT("AppleWin Error"), MB_OK);
|
||||
}
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-wav-speaker") == 0)
|
||||
{
|
||||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
lpNextArg = GetNextArg(lpNextArg);
|
||||
g_cmdLine.wavFileSpeaker = lpCmdLine;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-wav-mockingboard") == 0)
|
||||
{
|
||||
lpCmdLine = GetCurrArg(lpNextArg);
|
||||
lpNextArg = GetNextArg(lpNextArg);
|
||||
g_cmdLine.wavFileMockingboard = lpCmdLine;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-no-disk2-stepper-defer") == 0) // a debug switch (likely to be removed in a future version)
|
||||
{
|
||||
g_cmdLine.noDisk2StepperDefer = true;
|
||||
}
|
||||
else // unsupported
|
||||
{
|
||||
LogFileOutput("Unsupported arg: %s\n", lpCmdLine);
|
||||
|
|
|
@ -9,6 +9,16 @@
|
|||
|
||||
struct CmdLine
|
||||
{
|
||||
struct SlotInfo
|
||||
{
|
||||
SlotInfo()
|
||||
{
|
||||
isDiskII13 = false;
|
||||
}
|
||||
|
||||
bool isDiskII13;
|
||||
};
|
||||
|
||||
CmdLine()
|
||||
{
|
||||
bShutdown = false;
|
||||
|
@ -21,6 +31,8 @@ struct CmdLine
|
|||
snesMaxAltControllerType[0] = false;
|
||||
snesMaxAltControllerType[1] = false;
|
||||
supportDCD = false;
|
||||
enableDumpToRealPrinter = false;
|
||||
noDisk2StepperDefer = false;
|
||||
szImageName_harddisk[HARDDISK_1] = NULL;
|
||||
szImageName_harddisk[HARDDISK_2] = NULL;
|
||||
szSnapshotName = NULL;
|
||||
|
@ -61,7 +73,10 @@ struct CmdLine
|
|||
bool bRemoveNoSlotClock;
|
||||
bool snesMaxAltControllerType[2];
|
||||
bool supportDCD;
|
||||
bool enableDumpToRealPrinter;
|
||||
bool noDisk2StepperDefer; // debug
|
||||
SS_CARDTYPE slotInsert[NUM_SLOTS];
|
||||
SlotInfo slotInfo[NUM_SLOTS];
|
||||
LPCSTR szImageName_drive[NUM_SLOTS][NUM_DRIVES];
|
||||
bool driveConnected[NUM_SLOTS][NUM_DRIVES];
|
||||
LPCSTR szImageName_harddisk[NUM_HARDDISKS];
|
||||
|
@ -82,6 +97,8 @@ struct CmdLine
|
|||
bool bestFullScreenResolution;
|
||||
UINT userSpecifiedWidth;
|
||||
UINT userSpecifiedHeight;
|
||||
std::string wavFileSpeaker;
|
||||
std::string wavFileMockingboard;
|
||||
};
|
||||
|
||||
bool ProcessCmdLine(LPSTR lpCmdLine);
|
||||
|
|
|
@ -23,6 +23,7 @@ enum AppMode_e
|
|||
, MODE_DEBUG // 6502 is paused
|
||||
, MODE_STEPPING // 6502 is running at normal/full speed (Debugger breakpoints always active)
|
||||
, MODE_BENCHMARK
|
||||
, MODE_UNDEFINED // Used in SoundCore_SetFade()
|
||||
};
|
||||
|
||||
#define SPEED_MIN 0
|
||||
|
@ -67,6 +68,7 @@ enum AppMode_e
|
|||
#define REGVALUE_OLD_APPLE2_TYPE "Computer Emulation" // Deprecated
|
||||
#define REGVALUE_CONFIRM_REBOOT "Confirm Reboot" // Added at 1.24.1 PageConfig
|
||||
#define REGVALUE_FS_SHOW_SUBUNIT_STATUS "Full-screen show subunit status"
|
||||
#define REGVALUE_SHOW_DISKII_STATUS "Show Disk II Status"
|
||||
#define REGVALUE_SOUND_EMULATION "Sound Emulation"
|
||||
#define REGVALUE_SPKR_VOLUME "Speaker Volume"
|
||||
#define REGVALUE_MB_VOLUME "Mockingboard Volume"
|
||||
|
@ -108,12 +110,15 @@ enum AppMode_e
|
|||
#define REGVALUE_WINDOW_SCALE "Window Scale"
|
||||
#define REGVALUE_UTHERNET_ACTIVE "Uthernet Active" // GH#977: Deprecated from 1.30.5
|
||||
#define REGVALUE_UTHERNET_INTERFACE "Uthernet Interface"
|
||||
#define REGVALUE_UTHERNET_VIRTUAL_DNS "Uthernet Virtual DNS"
|
||||
#define REGVALUE_SLOT4 "Slot 4" // GH#977: Deprecated from 1.30.4
|
||||
#define REGVALUE_SLOT5 "Slot 5" // GH#977: Deprecated from 1.30.4
|
||||
#define REGVALUE_VERSION "Version"
|
||||
#define REG_CONFIG_SLOT_AUX "Slot Auxiliary"
|
||||
#define REG_CONFIG_SLOT "Slot "
|
||||
#define REGVALUE_CARD_TYPE "Card type"
|
||||
#define REG_CONFIG_GAME_IO_CONNECTOR "Game I/O Connector"
|
||||
#define REGVALUE_GAME_IO_TYPE "Game I/O type"
|
||||
#define REGVALUE_LAST_DISK_1 "Last Disk Image 1"
|
||||
#define REGVALUE_LAST_DISK_2 "Last Disk Image 2"
|
||||
#define REGVALUE_LAST_HARDDISK_1 "Last Harddisk Image 1"
|
||||
|
|
98
source/Configuration/Config.cpp
Normal file
98
source/Configuration/Config.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Config.h"
|
||||
#include "../CardManager.h"
|
||||
#include "../Interface.h" // VideoRefreshRate_e, GetVideoRefreshRate()
|
||||
#include "../Uthernet2.h"
|
||||
#include "../Tfe/PCapBackend.h"
|
||||
|
||||
// zero initialise
|
||||
CConfigNeedingRestart::CConfigNeedingRestart()
|
||||
{
|
||||
m_Apple2Type = A2TYPE_APPLE2;
|
||||
m_CpuType = CPU_UNKNOWN;
|
||||
memset(m_Slot, 0, sizeof(m_Slot));
|
||||
m_SlotAux = CT_Empty;
|
||||
m_tfeVirtualDNS = false;
|
||||
m_bEnableTheFreezesF8Rom = 0;
|
||||
m_uSaveLoadStateMsg = 0;
|
||||
m_videoRefreshRate = VR_NONE;
|
||||
}
|
||||
|
||||
// create from current global configuration
|
||||
CConfigNeedingRestart CConfigNeedingRestart::Create()
|
||||
{
|
||||
CConfigNeedingRestart config;
|
||||
config.Reload();
|
||||
return config;
|
||||
}
|
||||
|
||||
// update from current global configuration
|
||||
void CConfigNeedingRestart::Reload()
|
||||
{
|
||||
m_Apple2Type = GetApple2Type();
|
||||
m_CpuType = GetMainCpu();
|
||||
CardManager& cardManager = GetCardMgr();
|
||||
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
||||
m_Slot[slot] = cardManager.QuerySlot(slot);
|
||||
m_SlotAux = cardManager.QueryAux();
|
||||
m_tfeInterface = PCapBackend::GetRegistryInterface(SLOT3);
|
||||
m_tfeVirtualDNS = Uthernet2::GetRegistryVirtualDNS(SLOT3);
|
||||
m_bEnableTheFreezesF8Rom = GetPropertySheet().GetTheFreezesF8Rom();
|
||||
m_uSaveLoadStateMsg = 0;
|
||||
m_videoRefreshRate = GetVideo().GetVideoRefreshRate();
|
||||
}
|
||||
|
||||
const CConfigNeedingRestart& CConfigNeedingRestart::operator= (const CConfigNeedingRestart& other)
|
||||
{
|
||||
m_Apple2Type = other.m_Apple2Type;
|
||||
m_CpuType = other.m_CpuType;
|
||||
memcpy(m_Slot, other.m_Slot, sizeof(m_Slot));
|
||||
m_SlotAux = other.m_SlotAux;
|
||||
m_tfeInterface = other.m_tfeInterface;
|
||||
m_tfeVirtualDNS = other.m_tfeVirtualDNS;
|
||||
m_bEnableTheFreezesF8Rom = other.m_bEnableTheFreezesF8Rom;
|
||||
m_uSaveLoadStateMsg = other.m_uSaveLoadStateMsg;
|
||||
m_videoRefreshRate = other.m_videoRefreshRate;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CConfigNeedingRestart::operator== (const CConfigNeedingRestart& other) const
|
||||
{
|
||||
return m_Apple2Type == other.m_Apple2Type &&
|
||||
m_CpuType == other.m_CpuType &&
|
||||
memcmp(m_Slot, other.m_Slot, sizeof(m_Slot)) == 0 &&
|
||||
m_SlotAux == other.m_SlotAux &&
|
||||
m_tfeInterface == other.m_tfeInterface &&
|
||||
m_tfeVirtualDNS == other.m_tfeVirtualDNS &&
|
||||
m_bEnableTheFreezesF8Rom == other.m_bEnableTheFreezesF8Rom &&
|
||||
m_uSaveLoadStateMsg == other.m_uSaveLoadStateMsg &&
|
||||
m_videoRefreshRate == other.m_videoRefreshRate;
|
||||
}
|
||||
|
||||
bool CConfigNeedingRestart::operator!= (const CConfigNeedingRestart& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
|
@ -1,86 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include "../Core.h"
|
||||
#include "../CardManager.h"
|
||||
#include "../CPU.h"
|
||||
#include "../DiskImage.h" // Disk_Status_e
|
||||
#include "../Harddisk.h"
|
||||
#include "../Interface.h" // VideoRefreshRate_e, GetVideoRefreshRate()
|
||||
#include "../Tfe/PCapBackend.h"
|
||||
#include "../Video.h"
|
||||
|
||||
class CConfigNeedingRestart
|
||||
{
|
||||
public:
|
||||
// zero initialise
|
||||
CConfigNeedingRestart()
|
||||
{
|
||||
m_Apple2Type = A2TYPE_APPLE2;
|
||||
m_CpuType = CPU_UNKNOWN;
|
||||
memset(m_Slot, 0, sizeof(m_Slot));
|
||||
m_SlotAux = CT_Empty;
|
||||
m_bEnableTheFreezesF8Rom = 0;
|
||||
m_uSaveLoadStateMsg = 0;
|
||||
m_videoRefreshRate = VR_NONE;
|
||||
}
|
||||
CConfigNeedingRestart();
|
||||
|
||||
// create from current global configuration
|
||||
static CConfigNeedingRestart Create()
|
||||
{
|
||||
CConfigNeedingRestart config;
|
||||
config.Reload();
|
||||
return config;
|
||||
}
|
||||
static CConfigNeedingRestart Create();
|
||||
|
||||
// update from current global configuration
|
||||
void Reload()
|
||||
{
|
||||
m_Apple2Type = GetApple2Type();
|
||||
m_CpuType = GetMainCpu();
|
||||
CardManager& cardManager = GetCardMgr();
|
||||
for (UINT slot = SLOT0; slot < NUM_SLOTS; slot++)
|
||||
m_Slot[slot] = cardManager.QuerySlot(slot);
|
||||
m_SlotAux = cardManager.QueryAux();
|
||||
m_tfeInterface = PCapBackend::tfe_interface;
|
||||
m_bEnableTheFreezesF8Rom = GetPropertySheet().GetTheFreezesF8Rom();
|
||||
m_uSaveLoadStateMsg = 0;
|
||||
m_videoRefreshRate = GetVideo().GetVideoRefreshRate();
|
||||
}
|
||||
void Reload();
|
||||
|
||||
const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other)
|
||||
{
|
||||
m_Apple2Type = other.m_Apple2Type;
|
||||
m_CpuType = other.m_CpuType;
|
||||
memcpy(m_Slot, other.m_Slot, sizeof(m_Slot));
|
||||
m_SlotAux = other.m_SlotAux;
|
||||
m_tfeInterface = other.m_tfeInterface;
|
||||
m_bEnableTheFreezesF8Rom = other.m_bEnableTheFreezesF8Rom;
|
||||
m_uSaveLoadStateMsg = other.m_uSaveLoadStateMsg;
|
||||
m_videoRefreshRate = other.m_videoRefreshRate;
|
||||
return *this;
|
||||
}
|
||||
const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other);
|
||||
|
||||
bool operator== (const CConfigNeedingRestart& other) const
|
||||
{
|
||||
return m_Apple2Type == other.m_Apple2Type &&
|
||||
m_CpuType == other.m_CpuType &&
|
||||
memcmp(m_Slot, other.m_Slot, sizeof(m_Slot)) == 0 &&
|
||||
m_SlotAux == other.m_SlotAux &&
|
||||
m_tfeInterface == other.m_tfeInterface &&
|
||||
m_bEnableTheFreezesF8Rom == other.m_bEnableTheFreezesF8Rom &&
|
||||
m_uSaveLoadStateMsg == other.m_uSaveLoadStateMsg &&
|
||||
m_videoRefreshRate == other.m_videoRefreshRate;
|
||||
}
|
||||
bool operator== (const CConfigNeedingRestart& other) const;
|
||||
|
||||
bool operator!= (const CConfigNeedingRestart& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
bool operator!= (const CConfigNeedingRestart& other) const;
|
||||
|
||||
eApple2Type m_Apple2Type;
|
||||
eCpuType m_CpuType;
|
||||
SS_CARDTYPE m_Slot[NUM_SLOTS];
|
||||
SS_CARDTYPE m_SlotAux;
|
||||
std::string m_tfeInterface;
|
||||
bool m_tfeVirtualDNS;
|
||||
UINT m_bEnableTheFreezesF8Rom;
|
||||
UINT m_uSaveLoadStateMsg;
|
||||
VideoRefreshRate_e m_videoRefreshRate;
|
||||
|
|
|
@ -30,6 +30,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "../ParallelPrinter.h"
|
||||
#include "../Registry.h"
|
||||
#include "../SaveState.h"
|
||||
#include "../CardManager.h"
|
||||
#include "../CopyProtectionDongles.h"
|
||||
#include "../resource/resource.h"
|
||||
|
||||
CPageAdvanced* CPageAdvanced::ms_this = 0; // reinit'd in ctor
|
||||
|
@ -42,6 +44,11 @@ const TCHAR CPageAdvanced::m_CloneChoices[] =
|
|||
TEXT("TK3000 //e\0") // Brazilian
|
||||
TEXT("Base 64A\0"); // Taiwanese
|
||||
|
||||
//enum GAMEIOCONNECTOR_CHOICE { MENUITEM_EMPTY, MENUITEM_SPEEDSTAR };
|
||||
const TCHAR CPageAdvanced::m_gameIOConnectorChoices[] =
|
||||
TEXT("Empty\0")
|
||||
TEXT("SDS DataKey - SpeedStar\0"); // Protection dongle for Southwestern Data Systems "SpeedStar" Applesoft Compiler
|
||||
|
||||
|
||||
INT_PTR CALLBACK CPageAdvanced::DlgProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
|
@ -122,6 +129,13 @@ INT_PTR CPageAdvanced::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, L
|
|||
m_PropertySheetHelper.GetConfigNew().m_Apple2Type = NewCloneType;
|
||||
m_PropertySheetHelper.GetConfigNew().m_CpuType = ProbeMainCpuDefault(NewCloneType);
|
||||
}
|
||||
|
||||
case IDC_COMBO_GAME_IO_CONNECTOR:
|
||||
if (HIWORD(wparam) == CBN_SELCHANGE)
|
||||
{
|
||||
const DONGLETYPE newCopyProtectionDongleMenuItem = (DONGLETYPE)SendDlgItemMessage(hWnd, IDC_COMBO_GAME_IO_CONNECTOR, CB_GETCURSEL, 0, 0);
|
||||
SetCopyProtectionDongleType(newCopyProtectionDongleMenuItem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -131,19 +145,34 @@ INT_PTR CPageAdvanced::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, L
|
|||
SendDlgItemMessage(hWnd,IDC_SAVESTATE_FILENAME,WM_SETTEXT,0,(LPARAM)Snapshot_GetFilename().c_str());
|
||||
|
||||
CheckDlgButton(hWnd, IDC_SAVESTATE_ON_EXIT, g_bSaveStateOnExit ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hWnd, IDC_DUMPTOPRINTER, g_bDumpToPrinter ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hWnd, IDC_PRINTER_CONVERT_ENCODING, g_bConvertEncoding ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hWnd, IDC_PRINTER_FILTER_UNPRINTABLE, g_bFilterUnprintable ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hWnd, IDC_PRINTER_APPEND, g_bPrinterAppend ? BST_CHECKED : BST_UNCHECKED);
|
||||
SendDlgItemMessage(hWnd, IDC_SPIN_PRINTER_IDLE, UDM_SETRANGE, 0, MAKELONG(999,0));
|
||||
SendDlgItemMessage(hWnd, IDC_SPIN_PRINTER_IDLE, UDM_SETPOS, 0, MAKELONG(Printer_GetIdleLimit (),0));
|
||||
SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, WM_SETTEXT, 0, (LPARAM)Printer_GetFilename().c_str());
|
||||
|
||||
if (GetCardMgr().IsParallelPrinterCardInstalled())
|
||||
{
|
||||
ParallelPrinterCard* card = GetCardMgr().GetParallelPrinterCard();
|
||||
|
||||
CheckDlgButton(hWnd, IDC_DUMPTOPRINTER, card->GetDumpToPrinter() ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hWnd, IDC_PRINTER_CONVERT_ENCODING, card->GetConvertEncoding() ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hWnd, IDC_PRINTER_FILTER_UNPRINTABLE, card->GetFilterUnprintable() ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hWnd, IDC_PRINTER_APPEND, card->GetPrinterAppend() ? BST_CHECKED : BST_UNCHECKED);
|
||||
SendDlgItemMessage(hWnd, IDC_SPIN_PRINTER_IDLE, UDM_SETRANGE, 0, MAKELONG(999, 0));
|
||||
SendDlgItemMessage(hWnd, IDC_SPIN_PRINTER_IDLE, UDM_SETPOS, 0, MAKELONG(card->GetIdleLimit(), 0));
|
||||
SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, WM_SETTEXT, 0, (LPARAM)card->GetFilename().c_str());
|
||||
|
||||
// Need to specify cmd-line switch: -printer-real to enable this control
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_DUMPTOPRINTER), card->GetEnableDumpToRealPrinter() ? TRUE : FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_DUMPTOPRINTER), FALSE);
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_PRINTER_CONVERT_ENCODING), FALSE);
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_PRINTER_FILTER_UNPRINTABLE), FALSE);
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_PRINTER_APPEND), FALSE);
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_SPIN_PRINTER_IDLE), FALSE);
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_PRINTER_DUMP_FILENAME), FALSE);
|
||||
}
|
||||
|
||||
InitOptions(hWnd);
|
||||
|
||||
// Need to specify cmd-line switch: -printer-real to enable this control
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_DUMPTOPRINTER), g_bEnableDumpToRealPrinter ? TRUE : FALSE);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -160,42 +189,42 @@ void CPageAdvanced::DlgOK(HWND hWnd)
|
|||
m_PropertySheetHelper.SaveStateUpdate();
|
||||
}
|
||||
|
||||
// Update printer dump filename
|
||||
{
|
||||
char szFilename[MAX_PATH];
|
||||
memset(szFilename, 0, sizeof(szFilename));
|
||||
* (USHORT*) szFilename = sizeof(szFilename);
|
||||
|
||||
UINT nLineLength = SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, EM_LINELENGTH, 0, 0);
|
||||
|
||||
SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, EM_GETLINE, 0, (LPARAM)szFilename);
|
||||
|
||||
nLineLength = nLineLength > sizeof(szFilename)-1 ? sizeof(szFilename)-1 : nLineLength;
|
||||
szFilename[nLineLength] = 0x00;
|
||||
|
||||
Printer_SetFilename(szFilename);
|
||||
RegSaveString(TEXT(REG_CONFIG), REGVALUE_PRINTER_FILENAME, 1, Printer_GetFilename());
|
||||
}
|
||||
|
||||
g_bSaveStateOnExit = IsDlgButtonChecked(hWnd, IDC_SAVESTATE_ON_EXIT) ? true : false;
|
||||
REGSAVE(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), g_bSaveStateOnExit ? 1 : 0);
|
||||
|
||||
g_bDumpToPrinter = IsDlgButtonChecked(hWnd, IDC_DUMPTOPRINTER ) ? true : false;
|
||||
REGSAVE(TEXT(REGVALUE_DUMP_TO_PRINTER), g_bDumpToPrinter ? 1 : 0);
|
||||
// Save the copy protection dongle type
|
||||
RegSetConfigGameIOConnectorNewDongleType(GAME_IO_CONNECTOR, GetCopyProtectionDongleType());
|
||||
|
||||
g_bConvertEncoding = IsDlgButtonChecked(hWnd, IDC_PRINTER_CONVERT_ENCODING ) ? true : false;
|
||||
REGSAVE(TEXT(REGVALUE_CONVERT_ENCODING), g_bConvertEncoding ? 1 : 0);
|
||||
if (GetCardMgr().IsParallelPrinterCardInstalled())
|
||||
{
|
||||
ParallelPrinterCard* card = GetCardMgr().GetParallelPrinterCard();
|
||||
|
||||
g_bFilterUnprintable = IsDlgButtonChecked(hWnd, IDC_PRINTER_FILTER_UNPRINTABLE ) ? true : false;
|
||||
REGSAVE(TEXT(REGVALUE_FILTER_UNPRINTABLE), g_bFilterUnprintable ? 1 : 0);
|
||||
// Update printer dump filename
|
||||
{
|
||||
char szFilename[MAX_PATH];
|
||||
memset(szFilename, 0, sizeof(szFilename));
|
||||
*(USHORT*)szFilename = sizeof(szFilename);
|
||||
|
||||
g_bPrinterAppend = IsDlgButtonChecked(hWnd, IDC_PRINTER_APPEND) ? true : false;
|
||||
REGSAVE(TEXT(REGVALUE_PRINTER_APPEND), g_bPrinterAppend ? 1 : 0);
|
||||
UINT nLineLength = SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, EM_LINELENGTH, 0, 0);
|
||||
|
||||
//
|
||||
SendDlgItemMessage(hWnd, IDC_PRINTER_DUMP_FILENAME, EM_GETLINE, 0, (LPARAM)szFilename);
|
||||
|
||||
Printer_SetIdleLimit((short)SendDlgItemMessage(hWnd, IDC_SPIN_PRINTER_IDLE , UDM_GETPOS, 0, 0));
|
||||
REGSAVE(TEXT(REGVALUE_PRINTER_IDLE_LIMIT),Printer_GetIdleLimit());
|
||||
nLineLength = nLineLength > sizeof(szFilename) - 1 ? sizeof(szFilename) - 1 : nLineLength;
|
||||
szFilename[nLineLength] = 0x00;
|
||||
|
||||
card->SetFilename(szFilename);
|
||||
}
|
||||
|
||||
card->SetDumpToPrinter(IsDlgButtonChecked(hWnd, IDC_DUMPTOPRINTER) ? true : false);
|
||||
card->SetConvertEncoding(IsDlgButtonChecked(hWnd, IDC_PRINTER_CONVERT_ENCODING) ? true : false);
|
||||
card->SetFilterUnprintable(IsDlgButtonChecked(hWnd, IDC_PRINTER_FILTER_UNPRINTABLE) ? true : false);
|
||||
card->SetPrinterAppend(IsDlgButtonChecked(hWnd, IDC_PRINTER_APPEND) ? true : false);
|
||||
|
||||
card->SetIdleLimit((short)SendDlgItemMessage(hWnd, IDC_SPIN_PRINTER_IDLE, UDM_GETPOS, 0, 0));
|
||||
|
||||
// Now save all the above to Registry
|
||||
card->SetRegistryConfig();
|
||||
}
|
||||
|
||||
m_PropertySheetHelper.PostMsgAfterClose(hWnd, m_Page);
|
||||
}
|
||||
|
@ -204,6 +233,7 @@ void CPageAdvanced::InitOptions(HWND hWnd)
|
|||
{
|
||||
InitFreezeDlgButton(hWnd);
|
||||
InitCloneDropdownMenu(hWnd);
|
||||
InitGameIOConnectorDropdownMenu(hWnd);
|
||||
}
|
||||
|
||||
// Advanced->Clone: Menu item to eApple2Type
|
||||
|
@ -269,3 +299,10 @@ void CPageAdvanced::InitCloneDropdownMenu(HWND hWnd)
|
|||
const bool bIsClone = IsClone( m_PropertySheetHelper.GetConfigNew().m_Apple2Type );
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_CLONETYPE), bIsClone ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
void CPageAdvanced::InitGameIOConnectorDropdownMenu(HWND hWnd)
|
||||
{
|
||||
// Set copy protection dongle menu choice
|
||||
const int nCurrentChoice = GetCopyProtectionDongleType();
|
||||
m_PropertySheetHelper.FillComboBox(hWnd, IDC_COMBO_GAME_IO_CONNECTOR, m_gameIOConnectorChoices, nCurrentChoice);
|
||||
}
|
||||
|
|
|
@ -35,9 +35,11 @@ private:
|
|||
int GetCloneMenuItem(void);
|
||||
void InitFreezeDlgButton(HWND hWnd);
|
||||
void InitCloneDropdownMenu(HWND hWnd);
|
||||
void InitGameIOConnectorDropdownMenu(HWND hWnd);
|
||||
|
||||
static CPageAdvanced* ms_this;
|
||||
static const TCHAR m_CloneChoices[];
|
||||
static const TCHAR m_gameIOConnectorChoices[];
|
||||
|
||||
const PAGETYPE m_Page;
|
||||
CPropertySheetHelper& m_PropertySheetHelper;
|
||||
|
|
|
@ -30,6 +30,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "../Windows/Win32Frame.h"
|
||||
#include "../Registry.h"
|
||||
#include "../SerialComms.h"
|
||||
#include "../CardManager.h"
|
||||
#include "../Uthernet2.h"
|
||||
#include "../Tfe/PCapBackend.h"
|
||||
#include "../Interface.h"
|
||||
#include "../resource/resource.h"
|
||||
|
||||
CPageConfig* CPageConfig::ms_this = 0; // reinit'd in ctor
|
||||
|
@ -114,6 +118,7 @@ INT_PTR CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPA
|
|||
ui_tfe_settings_dialog(hWnd);
|
||||
m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT3] = m_PageConfigTfe.m_tfe_selected;
|
||||
m_PropertySheetHelper.GetConfigNew().m_tfeInterface = m_PageConfigTfe.m_tfe_interface_name;
|
||||
m_PropertySheetHelper.GetConfigNew().m_tfeVirtualDNS = m_PageConfigTfe.m_tfe_virtual_dns;
|
||||
InitOptions(hWnd);
|
||||
break;
|
||||
|
||||
|
@ -261,7 +266,8 @@ INT_PTR CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPA
|
|||
break;
|
||||
}
|
||||
|
||||
m_PageConfigTfe.m_tfe_interface_name = PCapBackend::tfe_interface;
|
||||
m_PageConfigTfe.m_tfe_interface_name = PCapBackend::GetRegistryInterface(SLOT3);
|
||||
m_PageConfigTfe.m_tfe_virtual_dns = Uthernet2::GetRegistryVirtualDNS(SLOT3);
|
||||
}
|
||||
|
||||
InitOptions(hWnd);
|
||||
|
|
|
@ -29,7 +29,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "../Registry.h"
|
||||
#include "../resource/resource.h"
|
||||
#include "../Tfe/PCapBackend.h"
|
||||
#include "../Tfe/tfesupp.h"
|
||||
|
||||
CPageConfigTfe* CPageConfigTfe::ms_this = 0; // reinit'd in ctor
|
||||
|
||||
|
@ -109,26 +108,23 @@ void CPageConfigTfe::DlgCANCEL(HWND window)
|
|||
EndDialog(window, 0);
|
||||
}
|
||||
|
||||
BOOL CPageConfigTfe::get_tfename(int number, char **ppname, char **ppdescription)
|
||||
BOOL CPageConfigTfe::get_tfename(int number, std::string & name, std::string & description)
|
||||
{
|
||||
if (PCapBackend::tfe_enumadapter_open())
|
||||
{
|
||||
char *pname = NULL;
|
||||
char *pdescription = NULL;
|
||||
std::string adapterName;
|
||||
std::string adapterDescription;
|
||||
|
||||
while (number--)
|
||||
{
|
||||
if (!PCapBackend::tfe_enumadapter(&pname, &pdescription))
|
||||
if (!PCapBackend::tfe_enumadapter(adapterName, adapterDescription))
|
||||
break;
|
||||
|
||||
lib_free(pname);
|
||||
lib_free(pdescription);
|
||||
}
|
||||
|
||||
if (PCapBackend::tfe_enumadapter(&pname, &pdescription))
|
||||
if (PCapBackend::tfe_enumadapter(adapterName, adapterDescription))
|
||||
{
|
||||
*ppname = pname;
|
||||
*ppdescription = pdescription;
|
||||
name = adapterName;
|
||||
description = adapterDescription;
|
||||
PCapBackend::tfe_enumadapter_close();
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -139,44 +135,21 @@ BOOL CPageConfigTfe::get_tfename(int number, char **ppname, char **ppdescription
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
int CPageConfigTfe::gray_ungray_items(HWND hwnd)
|
||||
void CPageConfigTfe::gray_ungray_items(HWND hwnd)
|
||||
{
|
||||
int enable;
|
||||
int number;
|
||||
|
||||
int disabled = 0;
|
||||
PCapBackend::get_disabled_state(&disabled);
|
||||
|
||||
if (disabled)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE_T), 0);
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), 0);
|
||||
EnableWindow(GetDlgItem(hwnd, IDOK), 0);
|
||||
SetWindowText(GetDlgItem(hwnd,IDC_TFE_SETTINGS_INTERFACE_NAME), "");
|
||||
SetWindowText(GetDlgItem(hwnd,IDC_TFE_SETTINGS_INTERFACE_DESC), "");
|
||||
enable = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
enable = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), CB_GETCURSEL, 0, 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_T), enable);
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE), enable);
|
||||
const int enable = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
char *pname = NULL;
|
||||
char *pdescription = NULL;
|
||||
std::string name;
|
||||
std::string description;
|
||||
|
||||
number = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE), CB_GETCURSEL, 0, 0);
|
||||
const int number = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE), CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (get_tfename(number, &pname, &pdescription))
|
||||
if (get_tfename(number, name, description))
|
||||
{
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_NAME), pname);
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), pdescription);
|
||||
lib_free(pname);
|
||||
lib_free(pdescription);
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_NAME), name.c_str());
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), description.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -185,7 +158,7 @@ int CPageConfigTfe::gray_ungray_items(HWND hwnd)
|
|||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), "");
|
||||
}
|
||||
|
||||
return disabled ? 1 : 0;
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_CHECK_TFE_VIRTUAL_DNS), enable == 2);
|
||||
}
|
||||
|
||||
void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
||||
|
@ -199,6 +172,23 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||
uilib_adjust_group_width(hwnd, ms_leftgroup);
|
||||
uilib_move_group(hwnd, ms_rightgroup, xsize + 30);
|
||||
|
||||
if (PCapBackend::tfe_is_npcap_loaded())
|
||||
{
|
||||
const char * version = PCapBackend::tfe_lib_version();
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_NPCAP_INFO), version);
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE), 0);
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_NAME), 0);
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), 0);
|
||||
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_NPCAP_INFO),
|
||||
"Limited Uthernet support is available on your system.\n\n"
|
||||
"Install Npcap from https://npcap.com\n"
|
||||
"or select Uthernet II with Virtual DNS.");
|
||||
}
|
||||
|
||||
switch (m_tfe_selected)
|
||||
{
|
||||
case CT_Uthernet:
|
||||
|
@ -212,6 +202,8 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||
break;
|
||||
}
|
||||
|
||||
CheckDlgButton(hwnd, IDC_CHECK_TFE_VIRTUAL_DNS, m_tfe_virtual_dns ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
temp_hwnd=GetDlgItem(hwnd,IDC_TFE_SETTINGS_ENABLE);
|
||||
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Disabled");
|
||||
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Uthernet");
|
||||
|
@ -222,25 +214,23 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||
{
|
||||
int cnt = 0;
|
||||
|
||||
char *pname;
|
||||
char *pdescription;
|
||||
std::string name;
|
||||
std::string description;
|
||||
|
||||
temp_hwnd=GetDlgItem(hwnd,IDC_TFE_SETTINGS_INTERFACE);
|
||||
|
||||
for (cnt = 0; PCapBackend::tfe_enumadapter(&pname, &pdescription); cnt++)
|
||||
for (cnt = 0; PCapBackend::tfe_enumadapter(name, description); cnt++)
|
||||
{
|
||||
BOOL this_entry = FALSE;
|
||||
|
||||
if (strcmp(pname, m_tfe_interface_name.c_str()) == 0)
|
||||
if (name == m_tfe_interface_name)
|
||||
{
|
||||
this_entry = TRUE;
|
||||
}
|
||||
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_NAME), pname);
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), pdescription);
|
||||
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)pname);
|
||||
lib_free(pname);
|
||||
lib_free(pdescription);
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_NAME), name.c_str());
|
||||
SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), description.c_str());
|
||||
SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)name.c_str());
|
||||
|
||||
if (this_entry)
|
||||
{
|
||||
|
@ -252,22 +242,7 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
|||
PCapBackend::tfe_enumadapter_close();
|
||||
}
|
||||
|
||||
if (gray_ungray_items(hwnd))
|
||||
{
|
||||
/* we have a problem: TFE is disabled. Give a message to the user */
|
||||
// TC (18 Dec 2017) this vicekb URL is a broken link now, so I copied it to the AppleWin repo, here:
|
||||
// . https://github.com/AppleWin/AppleWin/blob/master/docs/VICE%20Knowledge%20Base%20-%20Article%2013-005.htm
|
||||
MessageBox( hwnd,
|
||||
"Uthernet support is not available on your system,\n"
|
||||
"WPCAP.DLL cannot be loaded.\n\n"
|
||||
"Install Npcap from\n\n"
|
||||
" https://npcap.com\n\n"
|
||||
"to activate networking with AppleWin.",
|
||||
"Uthernet support", MB_ICONINFORMATION|MB_OK);
|
||||
|
||||
/* just quit the dialog before it is open */
|
||||
SendMessage( hwnd, WM_COMMAND, IDCANCEL, 0);
|
||||
}
|
||||
gray_ungray_items(hwnd);
|
||||
}
|
||||
|
||||
void CPageConfigTfe::save_tfe_dialog(HWND hwnd)
|
||||
|
@ -278,27 +253,21 @@ void CPageConfigTfe::save_tfe_dialog(HWND hwnd)
|
|||
buffer[255] = 0;
|
||||
GetDlgItemText(hwnd, IDC_TFE_SETTINGS_INTERFACE, buffer, sizeof(buffer)-1);
|
||||
|
||||
// RGJ - Added check for NULL interface so we don't set it active without a valid interface selected
|
||||
if (strlen(buffer) > 0)
|
||||
{
|
||||
m_tfe_interface_name = buffer;
|
||||
active_value = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), CB_GETCURSEL, 0, 0);
|
||||
switch (active_value)
|
||||
{
|
||||
case 1:
|
||||
m_tfe_selected = CT_Uthernet;
|
||||
break;
|
||||
case 2:
|
||||
m_tfe_selected = CT_Uthernet2;
|
||||
break;
|
||||
default:
|
||||
m_tfe_selected = CT_Empty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_tfe_interface_name = buffer;
|
||||
|
||||
active_value = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), CB_GETCURSEL, 0, 0);
|
||||
switch (active_value)
|
||||
{
|
||||
case 1:
|
||||
m_tfe_selected = CT_Uthernet;
|
||||
break;
|
||||
case 2:
|
||||
m_tfe_selected = CT_Uthernet2;
|
||||
break;
|
||||
default:
|
||||
m_tfe_selected = CT_Empty;
|
||||
m_tfe_interface_name.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
m_tfe_virtual_dns = IsDlgButtonChecked(hwnd, IDC_CHECK_TFE_VIRTUAL_DNS) ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ public:
|
|||
{
|
||||
CPageConfigTfe::ms_this = this;
|
||||
m_tfe_selected = CT_Empty;
|
||||
m_tfe_virtual_dns = false;
|
||||
}
|
||||
virtual ~CPageConfigTfe(){}
|
||||
|
||||
|
@ -20,6 +21,7 @@ public:
|
|||
|
||||
SS_CARDTYPE m_tfe_selected;
|
||||
std::string m_tfe_interface_name;
|
||||
bool m_tfe_virtual_dns;
|
||||
|
||||
protected:
|
||||
// IPropertySheetPage
|
||||
|
@ -28,8 +30,8 @@ protected:
|
|||
virtual void DlgCANCEL(HWND window);
|
||||
|
||||
private:
|
||||
BOOL get_tfename(int number, char **ppname, char **ppdescription);
|
||||
int gray_ungray_items(HWND hwnd);
|
||||
BOOL get_tfename(int number, std::string & name, std::string & description);
|
||||
void gray_ungray_items(HWND hwnd);
|
||||
void init_tfe_dialog(HWND hwnd);
|
||||
void save_tfe_dialog(HWND hwnd);
|
||||
|
||||
|
|
|
@ -27,9 +27,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "PropertySheet.h"
|
||||
|
||||
#include "../Windows/AppleWin.h"
|
||||
#include "../Windows/Win32Frame.h"
|
||||
#include "../CardManager.h"
|
||||
#include "../Disk.h" // Drive_e, Disk_Status_e
|
||||
#include "../Harddisk.h"
|
||||
#include "../Registry.h"
|
||||
#include "../Interface.h"
|
||||
#include "../resource/resource.h"
|
||||
|
||||
CPageDisk* CPageDisk::ms_this = 0; // reinit'd in ctor
|
||||
|
@ -180,6 +183,7 @@ INT_PTR CPageDisk::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARA
|
|||
case WM_INITDIALOG:
|
||||
{
|
||||
CheckDlgButton(hWnd, IDC_ENHANCE_DISK_ENABLE, GetCardMgr().GetDisk2CardMgr().GetEnhanceDisk() ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hWnd, IDC_DISKII_STATUS_ENABLE, Win32Frame::GetWin32Frame().GetWindowedModeShowDiskiiStatus() ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
const UINT slot = SLOT6;
|
||||
if (GetCardMgr().QuerySlot(slot) == CT_Disk2) // NB. SLOT6 not setup in m_PropertySheetHelper.GetConfigNew().m_Slot[]
|
||||
|
@ -277,6 +281,18 @@ void CPageDisk::DlgOK(HWND hWnd)
|
|||
REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), (DWORD)bNewEnhanceDisk);
|
||||
}
|
||||
|
||||
Win32Frame& win32Frame = Win32Frame::GetWin32Frame();
|
||||
const bool bNewDiskiiStatus = IsDlgButtonChecked(hWnd, IDC_DISKII_STATUS_ENABLE) ? true : false;
|
||||
|
||||
if (win32Frame.GetWindowedModeShowDiskiiStatus() != bNewDiskiiStatus)
|
||||
{
|
||||
REGSAVE(REGVALUE_SHOW_DISKII_STATUS, bNewDiskiiStatus ? 1 : 0);
|
||||
win32Frame.SetWindowedModeShowDiskiiStatus(bNewDiskiiStatus);
|
||||
|
||||
if (!win32Frame.IsFullScreen())
|
||||
win32Frame.FrameRefreshStatus(DRAW_BACKGROUND | DRAW_LEDS | DRAW_DISK_STATUS);
|
||||
}
|
||||
|
||||
m_PropertySheetHelper.PostMsgAfterClose(hWnd, m_Page);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#include "../Windows/AppleWin.h" // g_nAppMode, g_uScrollLockToggle, sg_PropertySheet
|
||||
#include "../CardManager.h"
|
||||
#include "../Memory.h"
|
||||
#include "../Disk.h"
|
||||
#include "../Log.h"
|
||||
#include "../Registry.h"
|
||||
#include "../SaveState.h"
|
||||
#include "../Interface.h"
|
||||
#include "../Uthernet2.h"
|
||||
#include "../Tfe/PCapBackend.h"
|
||||
|
||||
/*
|
||||
|
@ -130,6 +133,7 @@ void CPropertySheetHelper::SetSlot(UINT slot, SS_CARDTYPE newCardType)
|
|||
return;
|
||||
|
||||
GetCardMgr().Insert(slot, newCardType);
|
||||
GetCardMgr().GetRef(slot).InitializeIO(GetCxRomPeripheral());
|
||||
}
|
||||
|
||||
// Used by:
|
||||
|
@ -334,7 +338,8 @@ void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew
|
|||
SetSlot(slot, ConfigNew.m_Slot[slot]);
|
||||
|
||||
// unconditionally save it, as the previous SetSlot might have removed the setting
|
||||
PCapBackend::tfe_SetRegistryInterface(slot, ConfigNew.m_tfeInterface);
|
||||
PCapBackend::SetRegistryInterface(slot, ConfigNew.m_tfeInterface);
|
||||
Uthernet2::SetRegistryVirtualDNS(slot, ConfigNew.m_tfeVirtualDNS);
|
||||
|
||||
slot = SLOT4;
|
||||
if (CONFIG_CHANGED_LOCAL(m_Slot[slot]))
|
||||
|
@ -453,6 +458,9 @@ bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd)
|
|||
if (CONFIG_CHANGED(m_tfeInterface))
|
||||
strMsgMain += ". Uthernet interface has changed\n";
|
||||
|
||||
if (CONFIG_CHANGED(m_tfeVirtualDNS))
|
||||
strMsgMain += ". Uthernet Virtual DNS has changed\n";
|
||||
|
||||
if (CONFIG_CHANGED(m_Slot[SLOT4]))
|
||||
strMsgMain += GetSlot(SLOT4);
|
||||
|
||||
|
|
130
source/CopyProtectionDongles.cpp
Normal file
130
source/CopyProtectionDongles.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
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-2022, 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
|
||||
*/
|
||||
/*
|
||||
CopyProtectionDongles.cpp
|
||||
|
||||
Emulate hardware copy protection dongles for Apple II
|
||||
|
||||
Currently supported:
|
||||
- Southwestern Data Systems DataKey for SpeedStar Applesoft Compiler
|
||||
|
||||
Matthew D'Asaro Dec 2022
|
||||
*/
|
||||
#include "StdAfx.h"
|
||||
#include <sstream>
|
||||
|
||||
#include "CopyProtectionDongles.h"
|
||||
#include "Memory.h"
|
||||
#include "YamlHelper.h"
|
||||
|
||||
static DONGLETYPE copyProtectionDongleType = DT_EMPTY;
|
||||
|
||||
void SetCopyProtectionDongleType(DONGLETYPE type)
|
||||
{
|
||||
copyProtectionDongleType = type;
|
||||
}
|
||||
|
||||
DONGLETYPE GetCopyProtectionDongleType(void)
|
||||
{
|
||||
return copyProtectionDongleType;
|
||||
}
|
||||
|
||||
// This protection dongle consists of a NAND gate connected with AN1 and AN2 on the inputs
|
||||
// PB2 on the output, and AN0 connected to power it.
|
||||
bool SdsSpeedStar(void)
|
||||
{
|
||||
return !MemGetAnnunciator(0) || !(MemGetAnnunciator(1) && MemGetAnnunciator(2));
|
||||
}
|
||||
|
||||
// Returns the copy protection dongle state of PB0. A return value of -1 means not used by copy protection dongle
|
||||
int CopyProtectionDonglePB0(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Returns the copy protection dongle state of PB1. A return value of -1 means not used by copy protection dongle
|
||||
int CopyProtectionDonglePB1(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Returns the copy protection dongle state of PB2. A return value of -1 means not used by copy protection dongle
|
||||
int CopyProtectionDonglePB2(void)
|
||||
{
|
||||
switch (copyProtectionDongleType)
|
||||
{
|
||||
case DT_SDSSPEEDSTAR: // Southwestern Data Systems DataKey for SpeedStar Applesoft Compiler
|
||||
return SdsSpeedStar();
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static const UINT kUNIT_VERSION = 1;
|
||||
|
||||
static const std::string& GetSnapshotStructName_SDSSpeedStar(void)
|
||||
{
|
||||
static const std::string name("SDS SpeedStar dongle");
|
||||
return name;
|
||||
}
|
||||
|
||||
void CopyProtectionDongleSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||
{
|
||||
if (copyProtectionDongleType == DT_SDSSPEEDSTAR)
|
||||
{
|
||||
yamlSaveHelper.SaveString(SS_YAML_KEY_DEVICE, GetSnapshotStructName_SDSSpeedStar());
|
||||
// NB. No state for this dongle
|
||||
}
|
||||
else
|
||||
{
|
||||
_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CopyProtectionDongleLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
|
||||
{
|
||||
if (version < 1 || version > kUNIT_VERSION)
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "Version " << version;
|
||||
msg << " is not supported for game I/O device.";
|
||||
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
|
||||
std::string device = yamlLoadHelper.LoadString(SS_YAML_KEY_DEVICE);
|
||||
|
||||
if (device == GetSnapshotStructName_SDSSpeedStar())
|
||||
{
|
||||
copyProtectionDongleType = DT_SDSSPEEDSTAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ASSERT(0);
|
||||
}
|
||||
}
|
16
source/CopyProtectionDongles.h
Normal file
16
source/CopyProtectionDongles.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
// Must be in the same order as in PageAdvanced.cpp
|
||||
enum DONGLETYPE { DT_EMPTY, DT_SDSSPEEDSTAR };
|
||||
|
||||
void SetCopyProtectionDongleType(DONGLETYPE type);
|
||||
DONGLETYPE GetCopyProtectionDongleType(void);
|
||||
int CopyProtectionDonglePB0(void);
|
||||
int CopyProtectionDonglePB1(void);
|
||||
int CopyProtectionDonglePB2(void);
|
||||
bool SdsSpeedStar(void);
|
||||
|
||||
void CopyProtectionDongleSaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||
void CopyProtectionDongleLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version);
|
File diff suppressed because it is too large
Load Diff
|
@ -41,6 +41,9 @@
|
|||
, BP_HIT_INTERRUPT = (1 << 7)
|
||||
, BP_DMA_TO_IO_MEM = (1 << 8)
|
||||
, BP_DMA_FROM_IO_MEM = (1 << 9)
|
||||
, BP_DMA_TO_MEM = (1 << 10)
|
||||
, BP_DMA_FROM_MEM = (1 << 11)
|
||||
, BP_HIT_VIDEO_POS = (1 << 12)
|
||||
};
|
||||
|
||||
extern int g_nBreakpoints;
|
||||
|
@ -183,4 +186,5 @@
|
|||
void DebuggerMouseClick( int x, int y );
|
||||
|
||||
bool IsDebugSteppingAtFullSpeed(void);
|
||||
void DebuggerBreakOnDmaToOrFromIoMemory(WORD addr, bool isDmaToMemory);
|
||||
void DebuggerBreakOnDmaToOrFromIoMemory(WORD nAddress, bool isDmaToMemory);
|
||||
bool DebuggerCheckMemBreakpoints(WORD nAddress, WORD nSize, bool isDmaToMemory);
|
||||
|
|
|
@ -493,17 +493,19 @@ int _6502_GetOpmodeOpbyte ( const int nBaseAddress, int & iOpmode_, int & nOpby
|
|||
|
||||
// 2.7.0.0 TODO: FIXME: Opcode length that over-lap data, should be shortened ... if (nOpbyte_ > 1) if Disassembly_IsDataAddress( nBaseAddress + 1 ) nOpbyte_ = 1;
|
||||
DisasmData_t* pData = Disassembly_IsDataAddress( nBaseAddress );
|
||||
if( pData )
|
||||
if ( pData )
|
||||
{
|
||||
if( pData_ )
|
||||
if ( pData_ )
|
||||
*pData_ = pData;
|
||||
|
||||
nSlack = pData->nEndAddress - pData->nStartAddress + 1; // *inclusive* KEEP IN SYNC: _CmdDefineByteRange() CmdDisasmDataList() _6502_GetOpmodeOpbyte() FormatNopcodeBytes()
|
||||
const DWORD nEndAddress = pData->nEndAddress;
|
||||
const int nDisplayLen = nEndAddress - nBaseAddress + 1; // *inclusive* KEEP IN SYNC: _CmdDefineByteRange() CmdDisasmDataList() _6502_GetOpmodeOpbyte() FormatNopcodeBytes()
|
||||
nSlack = nDisplayLen;
|
||||
|
||||
// Data Disassembler
|
||||
// Smart Disassembly - Data Section
|
||||
// Assemblyer Directives - Psuedo Mnemonics
|
||||
switch( pData->eElementType )
|
||||
switch ( pData->eElementType )
|
||||
{
|
||||
case NOP_BYTE_1: nOpbyte_ = 1; iOpmode_ = AM_M; break;
|
||||
case NOP_BYTE_2: nOpbyte_ = 2; iOpmode_ = AM_M; break;
|
||||
|
@ -880,8 +882,8 @@ Hash_t AssemblerHashMnemonic ( const TCHAR * pMnemonic )
|
|||
}
|
||||
#endif
|
||||
|
||||
while( *pText )
|
||||
// for( int iChar = 0; iChar < 4; iChar++ )
|
||||
while ( *pText )
|
||||
// for ( int iChar = 0; iChar < 4; iChar++ )
|
||||
{
|
||||
char c = tolower( *pText ); // TODO: based on ALLOW_INPUT_LOWERCASE ??
|
||||
|
||||
|
@ -904,7 +906,7 @@ void AssemblerHashOpcodes ()
|
|||
Hash_t nMnemonicHash;
|
||||
int iOpcode;
|
||||
|
||||
for( iOpcode = 0; iOpcode < NUM_OPCODES; iOpcode++ )
|
||||
for ( iOpcode = 0; iOpcode < NUM_OPCODES; iOpcode++ )
|
||||
{
|
||||
const TCHAR *pMnemonic = g_aOpcodes65C02[ iOpcode ].sMnemonic;
|
||||
nMnemonicHash = AssemblerHashMnemonic( pMnemonic );
|
||||
|
@ -924,7 +926,7 @@ void AssemblerHashDirectives ()
|
|||
Hash_t nMnemonicHash;
|
||||
int iOpcode;
|
||||
|
||||
for( iOpcode = 0; iOpcode < NUM_ASM_M_DIRECTIVES; iOpcode++ )
|
||||
for ( iOpcode = 0; iOpcode < NUM_ASM_M_DIRECTIVES; iOpcode++ )
|
||||
{
|
||||
int iNopcode = FIRST_M_DIRECTIVE + iOpcode;
|
||||
//. const TCHAR *pMnemonic = g_aAssemblerDirectivesMerlin[ iOpcode ].m_pMnemonic;
|
||||
|
@ -949,7 +951,7 @@ void _CmdAssembleHashDump ()
|
|||
HashOpcode_t tHash;
|
||||
|
||||
int iOpcode;
|
||||
for( iOpcode = 0; iOpcode < NUM_OPCODES; iOpcode++ )
|
||||
for ( iOpcode = 0; iOpcode < NUM_OPCODES; iOpcode++ )
|
||||
{
|
||||
tHash.m_iOpcode = iOpcode;
|
||||
tHash.m_nValue = g_aOpcodesHash[ iOpcode ];
|
||||
|
@ -961,7 +963,7 @@ void _CmdAssembleHashDump ()
|
|||
// Hash_t nPrevHash = vHashes.at( 0 ).m_nValue;
|
||||
Hash_t nThisHash = 0;
|
||||
|
||||
for( iOpcode = 0; iOpcode < NUM_OPCODES; iOpcode++ )
|
||||
for ( iOpcode = 0; iOpcode < NUM_OPCODES; iOpcode++ )
|
||||
{
|
||||
tHash = vHashes.at( iOpcode );
|
||||
|
||||
|
@ -1020,7 +1022,7 @@ bool AssemblerPokeOpcodeAddress( const WORD nBaseAddress )
|
|||
int iOpcode;
|
||||
int nOpcodes = m_vAsmOpcodes.size();
|
||||
|
||||
for( iOpcode = 0; iOpcode < nOpcodes; iOpcode++ )
|
||||
for ( iOpcode = 0; iOpcode < nOpcodes; iOpcode++ )
|
||||
{
|
||||
int nOpcode = m_vAsmOpcodes.at( iOpcode ); // m_iOpcode;
|
||||
int nOpmode = g_aOpcodes[ nOpcode ].nAddressMode;
|
||||
|
@ -1405,7 +1407,7 @@ void AssemblerProcessDelayedSymols()
|
|||
bModified = false;
|
||||
|
||||
std::vector<DelayedTarget_t>::iterator iSymbol;
|
||||
for( iSymbol = m_vDelayedTargets.begin(); iSymbol != m_vDelayedTargets.end(); ++iSymbol )
|
||||
for ( iSymbol = m_vDelayedTargets.begin(); iSymbol != m_vDelayedTargets.end(); ++iSymbol )
|
||||
{
|
||||
DelayedTarget_t *pTarget = & (*iSymbol); // m_vDelayedTargets.at( iSymbol );
|
||||
|
||||
|
@ -1485,7 +1487,7 @@ bool Assemble( int iArg, int nArgs, WORD nAddress )
|
|||
int iOpcode;
|
||||
|
||||
// Ugh! Linear search.
|
||||
for( iOpcode = 0; iOpcode < NUM_OPCODES; iOpcode++ )
|
||||
for ( iOpcode = 0; iOpcode < NUM_OPCODES; iOpcode++ )
|
||||
{
|
||||
if (nMnemonicHash == g_aOpcodesHash[ iOpcode ])
|
||||
{
|
||||
|
|
|
@ -90,6 +90,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
{TEXT("BPM") , CmdBreakpointAddMemA , CMD_BREAKPOINT_ADD_MEM , "Add breakpoint on memory access" }, // SoftICE
|
||||
{TEXT("BPMR") , CmdBreakpointAddMemR , CMD_BREAKPOINT_ADD_MEMR , "Add breakpoint on memory read access" },
|
||||
{TEXT("BPMW") , CmdBreakpointAddMemW , CMD_BREAKPOINT_ADD_MEMW , "Add breakpoint on memory write access" },
|
||||
{TEXT("BPV") , CmdBreakpointAddVideo, CMD_BREAKPOINT_ADD_VIDEO , "Add breakpoint on video scanner position" },
|
||||
|
||||
{TEXT("BPC") , CmdBreakpointClear , CMD_BREAKPOINT_CLEAR , "Clear (remove) breakpoint" }, // SoftICE
|
||||
{TEXT("BPD") , CmdBreakpointDisable , CMD_BREAKPOINT_DISABLE , "Disable breakpoint- it is still in the list, just not active" }, // SoftICE
|
||||
|
@ -273,7 +274,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
{TEXT("DHGR2") , CmdViewOutput_DHGR2 , CMD_VIEW_DHGR2 , "View Double Hi-res Page 2" },
|
||||
{TEXT("SHR") , CmdViewOutput_SHR , CMD_VIEW_SHR , "View Super Hi-res" },
|
||||
// Watch
|
||||
{TEXT("W") , CmdWatch , CMD_WATCH , "Alias for WA (Watch Add)" },
|
||||
{TEXT("W") , CmdWatchAdd , CMD_WATCH , "Alias for WA (Watch Add)" },
|
||||
{TEXT("WA") , CmdWatchAdd , CMD_WATCH_ADD , "Add/Update address or symbol to watch" },
|
||||
{TEXT("WC") , CmdWatchClear , CMD_WATCH_CLEAR , "Clear (remove) watch" },
|
||||
{TEXT("WD") , CmdWatchDisable , CMD_WATCH_DISABLE , "Disable specific watch - it is still in the list, just not active" },
|
||||
|
@ -299,7 +300,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
// {TEXT("WINSOURCE") , CmdWindowShowSource , CMD_WINDOW_SOURCE },
|
||||
// {TEXT("ZEROPAGE") , CmdWindowShowZeropage, CMD_WINDOW_ZEROPAGE },
|
||||
// Zero Page
|
||||
{TEXT("ZP") , CmdZeroPage , CMD_ZEROPAGE_POINTER , "Alias for ZPA (Zero Page Add)" },
|
||||
{TEXT("ZP") , CmdZeroPageAdd , CMD_ZEROPAGE_POINTER , "Alias for ZPA (Zero Page Add)" },
|
||||
{TEXT("ZP0") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_0 , "Set/Update/Remove ZP watch 0 " },
|
||||
{TEXT("ZP1") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_1 , "Set/Update/Remove ZP watch 1" },
|
||||
{TEXT("ZP2") , CmdZeroPagePointer , CMD_ZEROPAGE_POINTER_2 , "Set/Update/Remove ZP watch 2" },
|
||||
|
@ -441,8 +442,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
{TEXT("SPACES") , NULL, PARAM_CONFIG_SPACES },
|
||||
{TEXT("TARGET") , NULL, PARAM_CONFIG_TARGET },
|
||||
// Disk
|
||||
{TEXT("EJECT") , NULL, PARAM_DISK_EJECT },
|
||||
{TEXT("INFO") , NULL, PARAM_DISK_INFO },
|
||||
{TEXT("SLOT") , NULL, PARAM_DISK_SET_SLOT },
|
||||
{TEXT("EJECT") , NULL, PARAM_DISK_EJECT },
|
||||
{TEXT("PROTECT") , NULL, PARAM_DISK_PROTECT },
|
||||
{TEXT("READ") , NULL, PARAM_DISK_READ },
|
||||
// Font (Config)
|
||||
|
@ -519,30 +521,25 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
void VerifyDebuggerCommandTable()
|
||||
{
|
||||
char sText[ CONSOLE_WIDTH * 2 ];
|
||||
|
||||
for (int iCmd = 0; iCmd < NUM_COMMANDS; iCmd++ )
|
||||
{
|
||||
if ( g_aCommands[ iCmd ].iCommand != iCmd)
|
||||
{
|
||||
sprintf( sText, "*** ERROR *** Enumerated Commands mis-matched at #%d!", iCmd );
|
||||
GetFrame().FrameMessageBox(sText, TEXT("ERROR"), MB_OK );
|
||||
std::string sText = StrFormat( "*** ERROR *** Enumerated Commands mis-matched at #%d!", iCmd );
|
||||
GetFrame().FrameMessageBox(sText.c_str(), "ERROR", MB_OK);
|
||||
PostQuitMessage( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// _tcscmp
|
||||
if (strcmp( g_aCommands[ NUM_COMMANDS ].m_sName, DEBUGGER__COMMANDS_VERIFY_TXT__))
|
||||
{
|
||||
sprintf( sText, "*** ERROR *** Total Commands mis-matched!" );
|
||||
GetFrame().FrameMessageBox(sText, TEXT("ERROR"), MB_OK );
|
||||
GetFrame().FrameMessageBox("*** ERROR *** Total Commands mis-matched!", "ERROR", MB_OK);
|
||||
PostQuitMessage( 1 );
|
||||
}
|
||||
|
||||
if (strcmp( g_aParameters[ NUM_PARAMS ].m_sName, DEBUGGER__PARAMS_VERIFY_TXT__))
|
||||
{
|
||||
sprintf( sText, "*** ERROR *** Total Parameters mis-matched!" );
|
||||
GetFrame().FrameMessageBox(sText, TEXT("ERROR"), MB_OK );
|
||||
GetFrame().FrameMessageBox("*** ERROR *** Total Parameters mis-matched!", "ERROR", MB_OK);
|
||||
PostQuitMessage( 2 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,7 +292,8 @@ void ConsoleBufferPush ( const char * pText )
|
|||
{
|
||||
g_nConsoleBuffer++;
|
||||
}
|
||||
pSrc++;
|
||||
if (c == '\n')
|
||||
pSrc++;
|
||||
pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
|
||||
}
|
||||
else
|
||||
|
@ -578,7 +579,7 @@ Update_t ConsoleScrollPageDn ()
|
|||
//===========================================================================
|
||||
Update_t ConsoleBufferTryUnpause (int nLines)
|
||||
{
|
||||
for( int y = 0; y < nLines; y++ )
|
||||
for ( int y = 0; y < nLines; y++ )
|
||||
{
|
||||
ConsoleBufferToDisplay();
|
||||
}
|
||||
|
|
|
@ -196,11 +196,11 @@
|
|||
const char *pSrc = pText;
|
||||
/* */ int nLen = 0;
|
||||
|
||||
if( pText )
|
||||
if ( pText )
|
||||
{
|
||||
while( *pSrc )
|
||||
while ( *pSrc )
|
||||
{
|
||||
if( ConsoleColor_IsCharMeta( *pSrc ) )
|
||||
if ( ConsoleColor_IsCharMeta( *pSrc ) )
|
||||
pSrc++;
|
||||
else
|
||||
nLen++;
|
||||
|
|
|
@ -27,6 +27,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#include "../Memory.h"
|
||||
|
||||
inline static void _memsetz(void* dst, int val, size_t len)
|
||||
{
|
||||
memset(dst, val, len);
|
||||
static_cast<char*>(dst)[len] = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
std::string FormatAddress(WORD nAddress, int nBytes)
|
||||
{
|
||||
|
@ -42,9 +48,9 @@ std::string FormatAddress(WORD nAddress, int nBytes)
|
|||
}
|
||||
|
||||
//===========================================================================
|
||||
char* FormatCharCopy(char* pDst, const char* pSrc, const int nLen)
|
||||
char* FormatCharCopy(char* pDst, const char* pEnd, const char* pSrc, const int nLen)
|
||||
{
|
||||
for (int i = 0; i < nLen; i++)
|
||||
for (int i = 0; i < nLen && pDst < pEnd; i++)
|
||||
*pDst++ = FormatCharTxtCtrl(*pSrc++);
|
||||
return pDst;
|
||||
}
|
||||
|
@ -236,22 +242,22 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_)
|
|||
nTarget = nBaseAddress + 2 + (int)(signed char)nTarget;
|
||||
|
||||
line_.nTarget = nTarget;
|
||||
sprintf(line_.sTargetValue, "%04X", nTarget & 0xFFFF);
|
||||
strncpy_s(line_.sTargetValue, WordToHexStr(nTarget & 0xFFFF).c_str(), _TRUNCATE);
|
||||
|
||||
// Always show branch indicators
|
||||
bDisasmFormatFlags |= DISASM_FORMAT_BRANCH;
|
||||
|
||||
if (nTarget < nBaseAddress)
|
||||
sprintf(line_.sBranch, "%s", g_sConfigBranchIndicatorUp[g_iConfigDisasmBranchType]);
|
||||
strncpy_s(line_.sBranch, g_sConfigBranchIndicatorUp[g_iConfigDisasmBranchType], _TRUNCATE);
|
||||
else
|
||||
if (nTarget > nBaseAddress)
|
||||
sprintf(line_.sBranch, "%s", g_sConfigBranchIndicatorDown[g_iConfigDisasmBranchType]);
|
||||
strncpy_s(line_.sBranch, g_sConfigBranchIndicatorDown[g_iConfigDisasmBranchType], _TRUNCATE);
|
||||
else
|
||||
sprintf(line_.sBranch, "%s", g_sConfigBranchIndicatorEqual[g_iConfigDisasmBranchType]);
|
||||
strncpy_s(line_.sBranch, g_sConfigBranchIndicatorEqual[g_iConfigDisasmBranchType], _TRUNCATE);
|
||||
|
||||
bDisasmFormatFlags |= DISASM_FORMAT_TARGET_POINTER;
|
||||
if (g_iConfigDisasmTargets & DISASM_TARGET_ADDR)
|
||||
sprintf(line_.sTargetPointer, "%04X", nTarget & 0xFFFF);
|
||||
strncpy_s(line_.sTargetPointer, WordToHexStr(nTarget & 0xFFFF).c_str(), _TRUNCATE);
|
||||
}
|
||||
// intentional re-test AM_R ...
|
||||
|
||||
|
@ -273,7 +279,7 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_)
|
|||
|
||||
std::string const* pTarget = NULL;
|
||||
std::string const* pSymbol = FindSymbolFromAddress(nTarget, &line_.iTargetTable);
|
||||
std::string strAddressBuf;
|
||||
std::string sAddressBuf;
|
||||
|
||||
// Data Assembler
|
||||
if (pData && (!pData->bSymbolLookup))
|
||||
|
@ -322,15 +328,15 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_)
|
|||
|
||||
if (!(bDisasmFormatFlags & DISASM_FORMAT_SYMBOL))
|
||||
{
|
||||
strAddressBuf = FormatAddress(nTarget, (iOpmode != AM_R) ? nOpbyte : 3); // GH#587: For Bcc opcodes, pretend it's a 3-byte opcode to print a 16-bit target addr
|
||||
pTarget = &strAddressBuf;
|
||||
sAddressBuf = FormatAddress(nTarget, (iOpmode != AM_R) ? nOpbyte : 3); // GH#587: For Bcc opcodes, pretend it's a 3-byte opcode to print a 16-bit target addr
|
||||
pTarget = &sAddressBuf;
|
||||
}
|
||||
|
||||
// sprintf( sTarget, g_aOpmodes[ iOpmode ]._sFormat, pTarget );
|
||||
//sTarget = StrFormat( g_aOpmodes[ iOpmode ].m_sFormat, pTarget->c_str() );
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_OFFSET)
|
||||
{
|
||||
int nAbsTargetOffset = (line_.nTargetOffset > 0) ? line_.nTargetOffset : -line_.nTargetOffset;
|
||||
sprintf(line_.sTargetOffset, "%d", nAbsTargetOffset);
|
||||
strncpy_s(line_.sTargetOffset, StrFormat("%d", nAbsTargetOffset).c_str(), _TRUNCATE);
|
||||
}
|
||||
strncpy_s(line_.sTarget, pTarget->c_str(), _TRUNCATE);
|
||||
|
||||
|
@ -348,70 +354,72 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_)
|
|||
|
||||
nTargetValue = *(mem + nTargetPointer) | (*(mem + ((nTargetPointer + 1) & 0xffff)) << 8);
|
||||
|
||||
// if (((iOpmode >= AM_A) && (iOpmode <= AM_NZ)) && (iOpmode != AM_R))
|
||||
// sprintf( sTargetValue_, "%04X", nTargetValue ); // & 0xFFFF
|
||||
//if (((iOpmode >= AM_A) && (iOpmode <= AM_NZ)) && (iOpmode != AM_R))
|
||||
// sTargetValue_ = WordToHexStr( nTargetValue ); // & 0xFFFF
|
||||
|
||||
if (g_iConfigDisasmTargets & DISASM_TARGET_ADDR)
|
||||
sprintf(line_.sTargetPointer, "%04X", nTargetPointer & 0xFFFF);
|
||||
strncpy_s(line_.sTargetPointer, WordToHexStr(nTargetPointer & 0xFFFF).c_str(), _TRUNCATE);
|
||||
|
||||
if (iOpcode != OPCODE_JMP_NA && iOpcode != OPCODE_JMP_IAX)
|
||||
{
|
||||
bDisasmFormatFlags |= DISASM_FORMAT_TARGET_VALUE;
|
||||
if (g_iConfigDisasmTargets & DISASM_TARGET_VAL)
|
||||
sprintf(line_.sTargetValue, "%02X", nTargetValue & 0xFF);
|
||||
strncpy_s(line_.sTargetValue, ByteToHexStr(nTargetValue & 0xFF).c_str(), _TRUNCATE);
|
||||
|
||||
bDisasmFormatFlags |= DISASM_FORMAT_CHAR;
|
||||
line_.nImmediate = (BYTE)nTargetValue;
|
||||
|
||||
unsigned _char = FormatCharTxtCtrl(FormatCharTxtHigh(line_.nImmediate, NULL), NULL);
|
||||
sprintf(line_.sImmediate, "%c", _char);
|
||||
const char _char = FormatCharTxtCtrl(FormatCharTxtHigh(line_.nImmediate, NULL), NULL);
|
||||
_memsetz(line_.sImmediate, _char, 1);
|
||||
|
||||
// if (ConsoleColorIsEscapeMeta( nImmediate_ ))
|
||||
//if (ConsoleColorIsEscapeMeta( nImmediate_ ))
|
||||
#if OLD_CONSOLE_COLOR
|
||||
if (ConsoleColorIsEscapeMeta(_char))
|
||||
sprintf(line_.sImmediate, "%c%c", _char, _char);
|
||||
_memsetz(line_.sImmediate, _char, 2);
|
||||
else
|
||||
sprintf(line_.sImmediate, "%c", _char);
|
||||
_memsetz(line_.sImmediate, _char, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// if (iOpmode == AM_NA ) // Indirect Absolute
|
||||
// sprintf( sTargetValue_, "%04X", nTargetPointer & 0xFFFF );
|
||||
// else
|
||||
// // sprintf( sTargetValue_, "%02X", nTargetValue & 0xFF );
|
||||
// sprintf( sTargetValue_, "%04X:%02X", nTargetPointer & 0xFFFF, nTargetValue & 0xFF );
|
||||
//if (iOpmode == AM_NA ) // Indirect Absolute
|
||||
// sTargetValue_ = WordToHexStr( nTargetPointer & 0xFFFF );
|
||||
//else
|
||||
// //sTargetValue_ = ByteToHexStr( nTargetValue & 0xFF );
|
||||
// sTargetValue_ = StrFormat( "%04X:%02X", nTargetPointer & 0xFFFF, nTargetValue & 0xFF );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iOpmode == AM_M)
|
||||
{
|
||||
// sprintf( sTarget, g_aOpmodes[ iOpmode ]._sFormat, (unsigned)nTarget );
|
||||
sprintf(line_.sTarget , "%02X", (unsigned)nTarget);
|
||||
strncpy_s(line_.sTarget, ByteToHexStr((BYTE)nTarget).c_str(), _TRUNCATE);
|
||||
|
||||
if (nTarget == 0)
|
||||
line_.sImmediateSignedDec[0] = 0; // nothing
|
||||
else
|
||||
if (nTarget < 128)
|
||||
sprintf(line_.sImmediateSignedDec, "+%d" , nTarget );
|
||||
strncpy_s(line_.sImmediateSignedDec, StrFormat("+%d", nTarget).c_str(), _TRUNCATE);
|
||||
else
|
||||
if (nTarget >= 128)
|
||||
sprintf(line_.sImmediateSignedDec, "-%d" , (~nTarget + 1) & 0xFF );
|
||||
strncpy_s(line_.sImmediateSignedDec, StrFormat("-%d" , (~nTarget + 1) & 0xFF).c_str(), _TRUNCATE);
|
||||
|
||||
bDisasmFormatFlags |= DISASM_FORMAT_CHAR;
|
||||
line_.nImmediate = (BYTE)nTarget;
|
||||
unsigned _char = FormatCharTxtCtrl(FormatCharTxtHigh(line_.nImmediate, NULL), NULL);
|
||||
|
||||
sprintf(line_.sImmediate, "%c", _char);
|
||||
const char _char = FormatCharTxtCtrl(FormatCharTxtHigh(line_.nImmediate, NULL), NULL);
|
||||
_memsetz(line_.sImmediate, _char, 1);
|
||||
|
||||
#if OLD_CONSOLE_COLOR
|
||||
if (ConsoleColorIsEscapeMeta(_char))
|
||||
sprintf(line_.sImmediate, "%c%c", _char, _char);
|
||||
_memsetz(line_.sImmediate, _char, 2);
|
||||
else
|
||||
sprintf(line_.sImmediate, "%c", _char);
|
||||
_memsetz(line_.sImmediate, _char, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(line_.sAddress, "%04X", nBaseAddress);
|
||||
strncpy_s(line_.sAddress, WordToHexStr(nBaseAddress).c_str(), _TRUNCATE);
|
||||
|
||||
// Opcode Bytes
|
||||
FormatOpcodeBytes(nBaseAddress, line_);
|
||||
|
@ -429,11 +437,11 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_)
|
|||
strcpy(line_.sMnemonic, g_aOpcodes[line_.iOpcode].sMnemonic);
|
||||
}
|
||||
|
||||
int nSpaces = strlen(line_.sOpCodes);
|
||||
while (nSpaces < (int)nMinBytesLen)
|
||||
const size_t nOpCodesLen = strlen(line_.sOpCodes);
|
||||
if (nOpCodesLen < nMinBytesLen)
|
||||
{
|
||||
strcat(line_.sOpCodes, " ");
|
||||
nSpaces++;
|
||||
memset(line_.sOpCodes + nOpCodesLen, ' ', nMinBytesLen - nOpCodesLen);
|
||||
line_.sOpCodes[nMinBytesLen] = '\0';
|
||||
}
|
||||
|
||||
return bDisasmFormatFlags;
|
||||
|
@ -442,32 +450,31 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_)
|
|||
//===========================================================================
|
||||
void FormatOpcodeBytes(WORD nBaseAddress, DisasmLine_t& line_)
|
||||
{
|
||||
int nOpbyte = line_.nOpbyte;
|
||||
|
||||
char* pDst = line_.sOpCodes;
|
||||
int nMaxOpBytes = nOpbyte;
|
||||
if (nMaxOpBytes > DISASM_DISPLAY_MAX_OPCODES) // 2.8.0.0 fix // TODO: FIX: show max 8 bytes for HEX
|
||||
nMaxOpBytes = DISASM_DISPLAY_MAX_OPCODES;
|
||||
// 2.8.0.0 fix // TODO: FIX: show max 8 bytes for HEX
|
||||
const int nMaxOpBytes = min(line_.nOpbyte, DISASM_DISPLAY_MAX_OPCODES);
|
||||
|
||||
char* cp = line_.sOpCodes;
|
||||
const char* const ep = cp + sizeof(line_.sOpCodes);
|
||||
for (int iByte = 0; iByte < nMaxOpBytes; iByte++)
|
||||
{
|
||||
BYTE nMem = mem[(nBaseAddress + iByte) & 0xFFFF];
|
||||
sprintf(pDst, "%02X", nMem); // sBytes+strlen(sBytes)
|
||||
pDst += 2;
|
||||
const BYTE nMem = mem[(nBaseAddress + iByte) & 0xFFFF];
|
||||
if ((cp+2) < ep)
|
||||
cp = StrBufferAppendByteAsHex(cp, nMem);
|
||||
|
||||
// TODO: If Disassembly_IsDataAddress() don't show spaces...
|
||||
if (g_bConfigDisasmOpcodeSpaces)
|
||||
{
|
||||
strcat(pDst, " ");
|
||||
pDst++; // 2.5.3.3 fix
|
||||
if ((cp+1) < ep)
|
||||
*cp++ = ' ';
|
||||
}
|
||||
}
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
struct FAC_t
|
||||
{
|
||||
uint8_t negative;
|
||||
int8_t exponent;
|
||||
uint8_t negative;
|
||||
int8_t exponent;
|
||||
uint32_t mantissa;
|
||||
|
||||
bool isZero;
|
||||
|
@ -507,13 +514,12 @@ void FAC_Unpack(WORD nAddress, FAC_t& fac_)
|
|||
//===========================================================================
|
||||
void FormatNopcodeBytes(WORD nBaseAddress, DisasmLine_t& line_)
|
||||
{
|
||||
char* pDst = line_.sTarget;
|
||||
const char* pSrc = 0;
|
||||
DWORD nStartAddress = line_.pDisasmData->nStartAddress;
|
||||
DWORD nEndAddress = line_.pDisasmData->nEndAddress;
|
||||
// int nDataLen = nEndAddress - nStartAddress + 1 ;
|
||||
int nDisplayLen = nEndAddress - nBaseAddress + 1; // *inclusive* KEEP IN SYNC: _CmdDefineByteRange() CmdDisasmDataList() _6502_GetOpmodeOpbyte() FormatNopcodeBytes()
|
||||
int len = nDisplayLen;
|
||||
// TODO: One day, line_.sTarget should become a std::string and things would be much simpler.
|
||||
char* pDst = line_.sTarget;
|
||||
const char* const pEnd = pDst + sizeof(line_.sTarget);
|
||||
const DWORD nStartAddress = line_.pDisasmData->nStartAddress;
|
||||
const DWORD nEndAddress = line_.pDisasmData->nEndAddress;
|
||||
const int nDisplayLen = nEndAddress - nBaseAddress + 1; // *inclusive* KEEP IN SYNC: _CmdDefineByteRange() CmdDisasmDataList() _6502_GetOpmodeOpbyte() FormatNopcodeBytes()
|
||||
|
||||
for (int iByte = 0; iByte < line_.nOpbyte; )
|
||||
{
|
||||
|
@ -526,14 +532,18 @@ void FormatNopcodeBytes(WORD nBaseAddress, DisasmLine_t& line_)
|
|||
case NOP_BYTE_2:
|
||||
case NOP_BYTE_4:
|
||||
case NOP_BYTE_8:
|
||||
sprintf(pDst, "%02X", nTarget8); // sBytes+strlen(sBytes)
|
||||
pDst += 2;
|
||||
if ((pDst + 2) < pEnd)
|
||||
pDst = StrBufferAppendByteAsHex(pDst, nTarget8);
|
||||
iByte++;
|
||||
if (line_.iNoptype == NOP_BYTE_1)
|
||||
{
|
||||
if (iByte < line_.nOpbyte)
|
||||
{
|
||||
*pDst++ = ',';
|
||||
if ((pDst + 1) < pEnd)
|
||||
*pDst++ = ',';
|
||||
}
|
||||
}
|
||||
*pDst = '\0';
|
||||
break;
|
||||
|
||||
case NOP_FAC:
|
||||
|
@ -542,27 +552,38 @@ void FormatNopcodeBytes(WORD nBaseAddress, DisasmLine_t& line_)
|
|||
FAC_Unpack( nBaseAddress, fac );
|
||||
const char aSign[2] = { '+', '-' };
|
||||
if (fac.isZero)
|
||||
sprintf( pDst, "0" );
|
||||
{
|
||||
if ((pDst + 1) < pEnd)
|
||||
*pDst++ = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
double f = fac.mantissa * pow( 2.0, fac.exponent - 32 );
|
||||
//sprintf( "s%1X m%04X e%02X", fac.negative, fac.mantissa, fac.exponent );
|
||||
sprintf( pDst, "%c%f", aSign[ fac.negative ], f );
|
||||
const double f = fac.mantissa * pow( 2.0, fac.exponent - 32 );
|
||||
//std::string sFac = StrFormat( "s%1X m%04X e%02X", fac.negative, fac.mantissa, fac.exponent );
|
||||
std::string sFac = StrFormat( "%c%f", aSign[ fac.negative ], f );
|
||||
if ((pDst + sFac.length()) < pEnd)
|
||||
{
|
||||
memcpy(pDst, sFac.c_str(), sFac.length());
|
||||
pDst += sFac.length();
|
||||
}
|
||||
}
|
||||
iByte += 5;
|
||||
*pDst = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
case NOP_WORD_1:
|
||||
case NOP_WORD_2:
|
||||
case NOP_WORD_4:
|
||||
sprintf(pDst, "%04X", nTarget16); // sBytes+strlen(sBytes)
|
||||
pDst += 4;
|
||||
if ((pDst + 4) < pEnd)
|
||||
pDst = StrBufferAppendWordAsHex(pDst, nTarget16);
|
||||
iByte += 2;
|
||||
if (iByte < line_.nOpbyte)
|
||||
{
|
||||
*pDst++ = ',';
|
||||
if ((pDst + 1) < pEnd)
|
||||
*pDst++ = ',';
|
||||
}
|
||||
*pDst = '\0';
|
||||
break;
|
||||
|
||||
case NOP_ADDRESS:
|
||||
|
@ -572,113 +593,124 @@ void FormatNopcodeBytes(WORD nBaseAddress, DisasmLine_t& line_)
|
|||
|
||||
case NOP_STRING_APPLESOFT:
|
||||
iByte = line_.nOpbyte;
|
||||
strncpy(pDst, (const char*)(mem + nBaseAddress), iByte);
|
||||
pDst += iByte;
|
||||
*pDst = 0;
|
||||
case NOP_STRING_APPLE:
|
||||
iByte = line_.nOpbyte; // handle all bytes of text
|
||||
pSrc = (const char*)mem + nStartAddress;
|
||||
|
||||
if (len > (DISASM_DISPLAY_MAX_IMMEDIATE_LEN - 2)) // does "text" fit?
|
||||
if ((pDst + iByte) < pEnd)
|
||||
{
|
||||
if (len > DISASM_DISPLAY_MAX_IMMEDIATE_LEN) // no; need extra characters for ellipsis?
|
||||
len = (DISASM_DISPLAY_MAX_IMMEDIATE_LEN - 3); // ellipsis = true
|
||||
memcpy(pDst, mem + nBaseAddress, iByte);
|
||||
pDst += iByte;
|
||||
}
|
||||
*pDst = 0;
|
||||
break;
|
||||
|
||||
case NOP_STRING_APPLE:
|
||||
{
|
||||
iByte = line_.nOpbyte; // handle all bytes of text
|
||||
const char* pSrc = (const char*)mem + nStartAddress;
|
||||
|
||||
if (nDisplayLen > (DISASM_DISPLAY_MAX_IMMEDIATE_LEN - 2)) // does "text" fit?
|
||||
{
|
||||
const bool ellipsis = (nDisplayLen > DISASM_DISPLAY_MAX_IMMEDIATE_LEN);
|
||||
const int len = (ellipsis) ? (DISASM_DISPLAY_MAX_IMMEDIATE_LEN - 3)
|
||||
: nDisplayLen // no need of extra characters for ellipsis
|
||||
;
|
||||
|
||||
// DISPLAY: text_longer_18...
|
||||
FormatCharCopy(pDst, pSrc, len); // BUG: #251 v2.8.0.7: ASC #:# with null byte doesn't mark up properly
|
||||
pDst = FormatCharCopy(pDst, pEnd, pSrc, len); // BUG: #251 v2.8.0.7: ASC #:# with null byte doesn't mark up properly
|
||||
|
||||
if (nDisplayLen > len) // ellipsis
|
||||
if (ellipsis && (pDst + 3) < pEnd)
|
||||
{
|
||||
*pDst++ = '.';
|
||||
*pDst++ = '.';
|
||||
*pDst++ = '.';
|
||||
}
|
||||
}
|
||||
else { // DISPLAY: "max_18_char"
|
||||
*pDst++ = '"';
|
||||
pDst = FormatCharCopy(pDst, pSrc, len); // BUG: #251 v2.8.0.7: ASC #:# with null byte doesn't mark up properly
|
||||
*pDst++ = '"';
|
||||
else
|
||||
{ // DISPLAY: "max_18_char"
|
||||
if ((pDst + 1) < pEnd)
|
||||
*pDst++ = '"';
|
||||
pDst = FormatCharCopy(pDst, pEnd, pSrc, nDisplayLen); // BUG: #251 v2.8.0.7: ASC #:# with null byte doesn't mark up properly
|
||||
if ((pDst + 1) < pEnd)
|
||||
*pDst++ = '"';
|
||||
}
|
||||
|
||||
*pDst = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
#if _DEBUG // Unhandled data disassembly!
|
||||
int* FATAL = 0;
|
||||
*FATAL = 0xDEADC0DE;
|
||||
#endif
|
||||
#if _DEBUG // Unhandled data disassembly!
|
||||
assert(false);
|
||||
#endif
|
||||
iByte++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // switch.
|
||||
} // for.
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void FormatDisassemblyLine(const DisasmLine_t& line, char* sDisassembly, const int nBufferSize)
|
||||
std::string FormatDisassemblyLine(const DisasmLine_t& line)
|
||||
{
|
||||
//> Address Seperator Opcodes Label Mnemonic Target [Immediate] [Branch]
|
||||
//> Address Separator Opcodes Label Mnemonic Target [Immediate] [Branch]
|
||||
//
|
||||
// Data Disassembler
|
||||
// Label Directive [Immediate]
|
||||
const char* pMnemonic = g_aOpcodes[line.iOpcode].sMnemonic;
|
||||
|
||||
sprintf(sDisassembly, "%s:%s %s "
|
||||
std::string sDisassembly = StrFormat( "%s:%s %s "
|
||||
, line.sAddress
|
||||
, line.sOpCodes
|
||||
, pMnemonic
|
||||
, g_aOpcodes[line.iOpcode].sMnemonic
|
||||
);
|
||||
|
||||
/*
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
{
|
||||
strcat( sDisassembly, "(" );
|
||||
}
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
sDisassembly += '(';
|
||||
|
||||
if (line.bTargetImmediate)
|
||||
strcat( sDisassembly, "#$" );
|
||||
if (line.bTargetImmediate)
|
||||
sDisassembly += "#$";
|
||||
|
||||
if (line.bTargetValue)
|
||||
strcat( sDisassembly, line.sTarget );
|
||||
if (line.bTargetValue)
|
||||
sDisassembly += line.sTarget;
|
||||
|
||||
if (line.bTargetIndirect)
|
||||
{
|
||||
if (line.bTargetX)
|
||||
strcat( sDisassembly, ", X" );
|
||||
if (line.bTargetY)
|
||||
strcat( sDisassembly, ", Y" );
|
||||
}
|
||||
if (line.bTargetIndirect)
|
||||
{
|
||||
if (line.bTargetX)
|
||||
sDisassembly += ", X";
|
||||
if (line.bTargetY)
|
||||
sDisassembly += ", Y";
|
||||
}
|
||||
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
{
|
||||
strcat( sDisassembly, ")" );
|
||||
}
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
sDisassembly += ')';
|
||||
|
||||
if (line.bTargetIndirect)
|
||||
{
|
||||
if (line.bTargetY)
|
||||
strcat( sDisassembly, ", Y" );
|
||||
}
|
||||
if (line.bTargetIndirect)
|
||||
{
|
||||
if (line.bTargetY)
|
||||
sDisassembly += ", Y";
|
||||
}
|
||||
*/
|
||||
char sTarget[32];
|
||||
|
||||
if (line.bTargetValue || line.bTargetRelative || line.bTargetImmediate)
|
||||
{
|
||||
if (line.bTargetRelative)
|
||||
strcpy(sTarget, line.sTargetValue);
|
||||
{
|
||||
sDisassembly += '$';
|
||||
sDisassembly += line.sTargetValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (line.bTargetImmediate)
|
||||
{
|
||||
strcat(sDisassembly, "#");
|
||||
strncpy(sTarget, line.sTarget, sizeof(sTarget));
|
||||
sTarget[sizeof(sTarget) - 1] = 0;
|
||||
sDisassembly += "#$";
|
||||
sDisassembly += line.sTarget;
|
||||
}
|
||||
else
|
||||
sprintf(sTarget, g_aOpmodes[line.iOpmode].m_sFormat, line.nTarget);
|
||||
|
||||
strcat(sDisassembly, "$");
|
||||
strcat(sDisassembly, sTarget);
|
||||
{
|
||||
sDisassembly += '$';
|
||||
sDisassembly += StrFormat( g_aOpmodes[line.iOpmode].m_sFormat, line.nTarget );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sDisassembly;
|
||||
}
|
||||
|
||||
// Given an Address, and Line to display it on
|
||||
|
@ -758,13 +790,12 @@ void DisasmCalcTopFromCurAddress(bool bUpdateTop)
|
|||
// Moving the cursor line around is not really a good idea, since we're breaking consistency paradigm for the user.
|
||||
// g_nDisasmCurLine = 0;
|
||||
#if 0 // _DEBUG
|
||||
TCHAR sText[CONSOLE_WIDTH * 2];
|
||||
sprintf(sText, TEXT("DisasmCalcTopFromCurAddress()\n"
|
||||
"\tTop: %04X\n"
|
||||
"\tLen: %04X\n"
|
||||
"\tMissed: %04X"),
|
||||
std::string sText = StrFormat("DisasmCalcTopFromCurAddress()\n"
|
||||
"\tTop: %04X\n"
|
||||
"\tLen: %04X\n"
|
||||
"\tMissed: %04X",
|
||||
g_nDisasmCurAddress - nLen, nLen, g_nDisasmCurAddress);
|
||||
GetFrame().FrameMessageBox(sText, "ERROR", MB_OK);
|
||||
GetFrame().FrameMessageBox(sText.c_str(), "ERROR", MB_OK);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
int GetDisassemblyLine(const WORD nOffset, DisasmLine_t& line_);
|
||||
// , int iOpcode, int iOpmode, int nOpbytes
|
||||
// char *sAddress_, char *sOpCodes_,
|
||||
// char *sTarget_, char *sTargetOffset_, int & nTargetOffset_, char *sTargetValue_,
|
||||
// char * sImmediate_, char & nImmediate_, char *sBranch_ );
|
||||
void FormatDisassemblyLine(const DisasmLine_t& line, char* sDisassembly_, const int nBufferSize);
|
||||
std::string FormatDisassemblyLine(const DisasmLine_t& line);
|
||||
void FormatOpcodeBytes(WORD nBaseAddress, DisasmLine_t& line_);
|
||||
void FormatNopcodeBytes(WORD nBaseAddress, DisasmLine_t& line_);
|
||||
|
||||
std::string FormatAddress(WORD nAddress, int nBytes);
|
||||
char* FormatCharCopy(char* pDst, const char* pSrc, const int nLen);
|
||||
char* FormatCharCopy(char* pDst, const char* pEnd, const char* pSrc, const int nLen);
|
||||
|
||||
char FormatCharTxtAsci(const BYTE b, bool* pWasAsci_ = NULL);
|
||||
char FormatCharTxtCtrl(const BYTE b, bool* pWasCtrl_ = NULL);
|
||||
|
|
|
@ -32,35 +32,31 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
// __ Debugger Interface ____________________________________________________________________________
|
||||
|
||||
void _GetAutoSymbolName ( const Nopcode_e &nopcode, const WORD nStartAddress, char *pSymbolName )
|
||||
std::string _GetAutoSymbolName(const Nopcode_e& nopcode, const WORD nStartAddress)
|
||||
{
|
||||
switch (nopcode)
|
||||
{
|
||||
case NOP_ADDRESS:
|
||||
sprintf( pSymbolName, "A_%04X", nStartAddress ); // DA range
|
||||
break;
|
||||
return StrFormat( "A_%04X", nStartAddress ); // DA range
|
||||
|
||||
case NOP_FAC:
|
||||
sprintf( pSymbolName, "F_%04X", nStartAddress ); // DF range
|
||||
return StrFormat( "F_%04X", nStartAddress ); // DF range
|
||||
|
||||
case NOP_STRING_ASCII:
|
||||
case NOP_STRING_APPLE:
|
||||
sprintf( pSymbolName, "T_%04X", nStartAddress ); // ASC range
|
||||
break;
|
||||
return StrFormat( "T_%04X", nStartAddress ); // ASC range
|
||||
|
||||
case NOP_WORD_1:
|
||||
case NOP_WORD_2:
|
||||
case NOP_WORD_4:
|
||||
sprintf( pSymbolName, "W_%04X", nStartAddress ); // DW range
|
||||
break;
|
||||
return StrFormat( "W_%04X", nStartAddress ); // DW range
|
||||
|
||||
case NOP_BYTE_1:
|
||||
case NOP_BYTE_2:
|
||||
case NOP_BYTE_4:
|
||||
case NOP_BYTE_8:
|
||||
default:
|
||||
sprintf( pSymbolName, "B_%04X", nStartAddress ); // DB range
|
||||
break;
|
||||
return StrFormat( "B_%04X", nStartAddress ); // DB range
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,9 +109,9 @@ WORD _GetDataRange (int nArgs, int iArg, DisasmData_t& tData_)
|
|||
|
||||
// 2.7.0.35 DW address -- round the length up to even number for convenience.
|
||||
// Example: 'DW 6062' is equivalent to: 'DW 6062:6063'
|
||||
if( g_iCommand == CMD_DEFINE_DATA_WORD1 )
|
||||
if ( g_iCommand == CMD_DEFINE_DATA_WORD1 )
|
||||
{
|
||||
if( ~nLen & 1 )
|
||||
if ( ~nLen & 1 )
|
||||
nLen++;
|
||||
}
|
||||
|
||||
|
@ -135,22 +131,21 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_)
|
|||
|
||||
nAddress = _GetDataRange(nArgs,iArg,tData_);
|
||||
|
||||
const char *pSymbolName = "";
|
||||
char aSymbolName[ MAX_SYMBOLS_LEN+1 ];
|
||||
std::string sSymbolName;
|
||||
|
||||
SymbolTable_Index_e eSymbolTable = SYMBOLS_ASSEMBLY;
|
||||
bool bAutoDefineName = false; // 2.7.0.34
|
||||
|
||||
if( nArgs > 1 )
|
||||
if ( nArgs > 1 )
|
||||
{
|
||||
if( g_aArgs[ 2 ].eToken == TOKEN_COLON ) // 2.7.0.31 Bug fix: DB range, i.e. DB 174E:174F
|
||||
if ( g_aArgs[ 2 ].eToken == TOKEN_COLON ) // 2.7.0.31 Bug fix: DB range, i.e. DB 174E:174F
|
||||
{
|
||||
bAutoDefineName = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_aArgs[ 1 ].sArg[MAX_SYMBOLS_LEN] = 0; // truncate to max symbol length
|
||||
pSymbolName = g_aArgs[1].sArg;
|
||||
sSymbolName = g_aArgs[1].sArg;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -162,33 +157,32 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_)
|
|||
// Old name: auto define D_# DB $XX
|
||||
// Example 'DB' or 'DW' with 1 arg
|
||||
// DB 801
|
||||
Nopcode_e nopcode = NOP_BYTE_1;
|
||||
Nopcode_e nopcode = NOP_BYTE_1;
|
||||
|
||||
bool isFloat = (g_iCommand == CMD_DEFINE_DATA_FLOAT);
|
||||
if( isFloat )
|
||||
nopcode = NOP_FAC;
|
||||
bool isFloat = (g_iCommand == CMD_DEFINE_DATA_FLOAT);
|
||||
if ( isFloat )
|
||||
nopcode = NOP_FAC;
|
||||
|
||||
bool isString = (g_iCommand == CMD_DEFINE_DATA_STR);
|
||||
if( isString )
|
||||
nopcode = NOP_STRING_ASCII;
|
||||
bool isString = (g_iCommand == CMD_DEFINE_DATA_STR);
|
||||
if ( isString )
|
||||
nopcode = NOP_STRING_ASCII;
|
||||
|
||||
bool isWord1 = (g_iCommand == CMD_DEFINE_DATA_WORD1);
|
||||
if( isWord1 )
|
||||
nopcode = NOP_WORD_1;
|
||||
bool isWord1 = (g_iCommand == CMD_DEFINE_DATA_WORD1);
|
||||
if ( isWord1 )
|
||||
nopcode = NOP_WORD_1;
|
||||
|
||||
bool isAddr = (g_iCommand == CMD_DEFINE_ADDR_WORD);
|
||||
if( isAddr )
|
||||
nopcode = NOP_ADDRESS;
|
||||
bool isAddr = (g_iCommand == CMD_DEFINE_ADDR_WORD);
|
||||
if ( isAddr )
|
||||
nopcode = NOP_ADDRESS;
|
||||
|
||||
if( bAutoDefineName )
|
||||
if ( bAutoDefineName )
|
||||
{
|
||||
_GetAutoSymbolName( nopcode, tData_.nStartAddress , aSymbolName );
|
||||
pSymbolName = aSymbolName;
|
||||
sSymbolName = _GetAutoSymbolName( nopcode, tData_.nStartAddress );
|
||||
}
|
||||
|
||||
// bRemoveSymbol = false // use arg[2]
|
||||
// bUpdateSymbol = true // add the symbol to the table
|
||||
SymbolUpdate( eSymbolTable, pSymbolName, nAddress, false, true );
|
||||
SymbolUpdate( eSymbolTable, sSymbolName.c_str(), nAddress, false, true );
|
||||
|
||||
// TODO: Note: need to call ConsoleUpdate(), as may print symbol has been updated
|
||||
|
||||
|
@ -196,7 +190,7 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_)
|
|||
// tData_.eElementType = nopcode;
|
||||
// As that is done by the caller.
|
||||
|
||||
strcpy_s( tData_.sSymbol, sizeof(tData_.sSymbol), pSymbolName );
|
||||
strncpy_s( tData_.sSymbol, sSymbolName.c_str(), _TRUNCATE );
|
||||
|
||||
return nAddress;
|
||||
}
|
||||
|
@ -264,7 +258,7 @@ Update_t CmdDisasmDataDefCode (int nArgs)
|
|||
while (nAddress <= tData.nEndAddress)
|
||||
{
|
||||
DisasmData_t *pData = Disassembly_IsDataAddress( nAddress );
|
||||
if( pData )
|
||||
if ( pData )
|
||||
{
|
||||
if (( nAddress <= pData->nStartAddress)
|
||||
&& (tData.nEndAddress >= pData->nEndAddress ))
|
||||
|
@ -294,12 +288,11 @@ Update_t CmdDisasmDataDefCode (int nArgs)
|
|||
DisasmData_t tSplit = *pData;
|
||||
pData->nEndAddress = nAddress - 1;
|
||||
|
||||
const char *pSymbolName = tSplit.sSymbol;
|
||||
|
||||
tSplit.nStartAddress = tData.nEndAddress + 1; // nAddress + 1;
|
||||
_GetAutoSymbolName( pData->eElementType, tSplit.nStartAddress, tSplit.sSymbol );
|
||||
std::string sSymbolName = _GetAutoSymbolName( pData->eElementType, tSplit.nStartAddress );
|
||||
strncpy_s(tSplit.sSymbol, sSymbolName.c_str(), _TRUNCATE);
|
||||
|
||||
SymbolUpdate( eSymbolTable, pSymbolName, tSplit.nStartAddress, false, true );
|
||||
SymbolUpdate( eSymbolTable, tSplit.sSymbol, tSplit.nStartAddress, false, true );
|
||||
Disassembly_AddData( tSplit );
|
||||
}
|
||||
|
||||
|
@ -342,24 +335,20 @@ Update_t CmdDisasmDataList (int nArgs)
|
|||
// Need to iterate through all blocks
|
||||
DisasmData_t* pData = NULL;
|
||||
|
||||
while( (pData = Disassembly_Enumerate( pData )) )
|
||||
while ( (pData = Disassembly_Enumerate( pData )) )
|
||||
{
|
||||
if (pData->iDirective != _NOP_REMOVED)
|
||||
{
|
||||
int nLen = strlen( pData->sSymbol );
|
||||
bool hasSymbol = pData->sSymbol[0] != '\0';
|
||||
|
||||
// <smbol> <type> <start>:<end>
|
||||
// <symbol> <type> <start>:<end>
|
||||
// `TEST `300`:`320
|
||||
ConsolePrintFormat( "%s%s %s%*s %s%04X%s:%s%04X"
|
||||
, CHC_CATEGORY
|
||||
ConsolePrintFormat( CHC_CATEGORY "%s %s%*s " CHC_ADDRESS "%04X" CHC_ARG_SEP ":" CHC_ADDRESS "%04X"
|
||||
, g_aNopcodeTypes[ pData->eElementType ]
|
||||
, (nLen > 0) ? CHC_SYMBOL : CHC_DEFAULT
|
||||
, hasSymbol ? CHC_SYMBOL : CHC_DEFAULT
|
||||
, MAX_SYMBOLS_LEN
|
||||
, (nLen > 0) ? pData->sSymbol : "???"
|
||||
, CHC_ADDRESS
|
||||
, hasSymbol ? pData->sSymbol : "???"
|
||||
, pData->nStartAddress
|
||||
, CHC_ARG_SEP
|
||||
, CHC_ADDRESS
|
||||
, pData->nEndAddress // Disassembly_IsDataAddress() is *inclusive* // KEEP IN SYNC: _CmdDefineByteRange() CmdDisasmDataList() _6502_GetOpmodeOpbyte() FormatNopcodeBytes()
|
||||
);
|
||||
}
|
||||
|
@ -411,7 +400,7 @@ Update_t _CmdDisasmDataDefByteX (int nArgs)
|
|||
|
||||
// Already exists, so update
|
||||
DisasmData_t *pData = Disassembly_IsDataAddress( nAddress );
|
||||
if( pData )
|
||||
if ( pData )
|
||||
{
|
||||
*pData = tData;
|
||||
}
|
||||
|
@ -462,7 +451,7 @@ Update_t _CmdDisasmDataDefWordX (int nArgs)
|
|||
|
||||
// Already exists, so update
|
||||
DisasmData_t *pData = Disassembly_IsDataAddress( nAddress );
|
||||
if( pData )
|
||||
if ( pData )
|
||||
{
|
||||
*pData = tData;
|
||||
}
|
||||
|
@ -514,7 +503,7 @@ Update_t CmdDisasmDataDefAddress16 (int nArgs)
|
|||
|
||||
// Already exists, so update
|
||||
DisasmData_t *pData = Disassembly_IsDataAddress( nAddress );
|
||||
if( pData )
|
||||
if ( pData )
|
||||
{
|
||||
*pData = tData;
|
||||
}
|
||||
|
@ -629,7 +618,7 @@ Update_t CmdDisasmDataDefString ( int nArgs )
|
|||
|
||||
// Already exists, so update
|
||||
DisasmData_t *pData = Disassembly_IsDataAddress( nAddress );
|
||||
if( pData )
|
||||
if ( pData )
|
||||
{
|
||||
*pData = tData;
|
||||
}
|
||||
|
@ -646,14 +635,14 @@ Update_t CmdDisasmDataDefString ( int nArgs )
|
|||
DisasmData_t* Disassembly_Enumerate( DisasmData_t *pCurrent )
|
||||
{
|
||||
DisasmData_t *pData = NULL; // bIsNopcode = false
|
||||
int nDataTargets = g_aDisassemblerData.size();
|
||||
size_t nDataTargets = g_aDisassemblerData.size();
|
||||
|
||||
if( nDataTargets )
|
||||
if ( nDataTargets > 0 )
|
||||
{
|
||||
DisasmData_t *pBegin = & g_aDisassemblerData[ 0 ];
|
||||
DisasmData_t *pEnd = & g_aDisassemblerData[ nDataTargets - 1 ];
|
||||
|
||||
if( pCurrent )
|
||||
if ( pCurrent )
|
||||
{
|
||||
pCurrent++;
|
||||
if (pCurrent <= pEnd)
|
||||
|
@ -670,17 +659,17 @@ DisasmData_t* Disassembly_Enumerate( DisasmData_t *pCurrent )
|
|||
DisasmData_t* Disassembly_IsDataAddress ( WORD nAddress )
|
||||
{
|
||||
DisasmData_t *pData = NULL; // bIsNopcode = false
|
||||
int nDataTargets = g_aDisassemblerData.size();
|
||||
size_t nDataTargets = g_aDisassemblerData.size();
|
||||
|
||||
if( nDataTargets )
|
||||
if ( nDataTargets > 0 )
|
||||
{
|
||||
// TODO: Replace with binary search -- should store data in sorted order, via start address
|
||||
pData = & g_aDisassemblerData[ 0 ];
|
||||
for( int iTarget = 0; iTarget < nDataTargets; iTarget++ )
|
||||
for ( size_t iTarget = 0; iTarget < nDataTargets; iTarget++ )
|
||||
{
|
||||
if( pData->iDirective != _NOP_REMOVED )
|
||||
if ( pData->iDirective != _NOP_REMOVED )
|
||||
{
|
||||
if( (nAddress >= pData->nStartAddress) && (nAddress <= pData->nEndAddress) )
|
||||
if ( (nAddress >= pData->nStartAddress) && (nAddress <= pData->nEndAddress) )
|
||||
{
|
||||
return pData;
|
||||
}
|
||||
|
@ -703,7 +692,7 @@ void Disassembly_AddData( DisasmData_t tData)
|
|||
//===========================================================================
|
||||
void Disassembly_GetData ( WORD nBaseAddress, const DisasmData_t *pData, DisasmLine_t & line_ )
|
||||
{
|
||||
if( !pData )
|
||||
if ( !pData )
|
||||
{
|
||||
#if _DEBUG
|
||||
ConsoleDisplayError( "Disassembly_GetData() but we don't have a valid DisasmData_t *" );
|
||||
|
@ -719,13 +708,13 @@ void Disassembly_DelData( DisasmData_t tData)
|
|||
WORD nAddress = tData.nStartAddress;
|
||||
|
||||
DisasmData_t *pData = NULL; // bIsNopcode = false
|
||||
int nDataTargets = g_aDisassemblerData.size();
|
||||
size_t nDataTargets = g_aDisassemblerData.size();
|
||||
|
||||
if( nDataTargets )
|
||||
if ( nDataTargets > 0 )
|
||||
{
|
||||
// TODO: Replace with binary search -- should store data in sorted order, via start address
|
||||
pData = & g_aDisassemblerData[ 0 ];
|
||||
for( int iTarget = 0; iTarget < nDataTargets; iTarget++ )
|
||||
for ( size_t iTarget = 0; iTarget < nDataTargets; iTarget++ )
|
||||
{
|
||||
if (pData->iDirective != _NOP_REMOVED)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,65 +52,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
*/
|
||||
|
||||
// tests if pSrc fits into pDst
|
||||
// returns true if pSrc safely fits into pDst, else false (pSrc would of overflowed pDst)
|
||||
//===========================================================================
|
||||
bool TestStringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize )
|
||||
{
|
||||
int nLenDst = _tcslen( pDst );
|
||||
int nLenSrc = _tcslen( pSrc );
|
||||
int nSpcDst = nDstSize - nLenDst;
|
||||
|
||||
bool bOverflow = (nSpcDst <= nLenSrc); // 2.5.6.25 BUGFIX
|
||||
if (bOverflow)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// tests if pSrc fits into pDst
|
||||
// returns true if pSrc safely fits into pDst, else false (pSrc would of overflowed pDst)
|
||||
//===========================================================================
|
||||
bool TryStringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize )
|
||||
{
|
||||
int nLenDst = _tcslen( pDst );
|
||||
int nLenSrc = _tcslen( pSrc );
|
||||
int nSpcDst = nDstSize - nLenDst;
|
||||
int nChars = MIN( nLenSrc, nSpcDst );
|
||||
|
||||
bool bOverflow = (nSpcDst < nLenSrc);
|
||||
if (bOverflow)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_tcsncat( pDst, pSrc, nChars );
|
||||
return true;
|
||||
}
|
||||
|
||||
// cats string as much as possible
|
||||
// returns true if pSrc safely fits into pDst, else false (pSrc would of overflowed pDst)
|
||||
//===========================================================================
|
||||
int StringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize )
|
||||
{
|
||||
int nLenDst = _tcslen( pDst );
|
||||
int nLenSrc = _tcslen( pSrc );
|
||||
int nSpcDst = nDstSize - nLenDst;
|
||||
int nChars = MIN( nLenSrc, nSpcDst );
|
||||
|
||||
_tcsncat( pDst, pSrc, nChars );
|
||||
|
||||
bool bOverflow = (nSpcDst < nLenSrc);
|
||||
if (bOverflow)
|
||||
return 0;
|
||||
|
||||
return nChars;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Help ___________________________________________________________________________________________
|
||||
|
||||
|
||||
|
@ -136,74 +77,48 @@ Update_t Help_Arg_1( int iCommandHelp )
|
|||
//===========================================================================
|
||||
void Help_Categories()
|
||||
{
|
||||
const int nBuf = CONSOLE_WIDTH * 2;
|
||||
|
||||
char sText[ nBuf ] = "";
|
||||
int nLen = 0;
|
||||
|
||||
// TODO/FIXME: Colorize( sText, ... )
|
||||
// Colorize("Usage:")
|
||||
nLen += StringCat( sText, CHC_USAGE , nBuf );
|
||||
nLen += StringCat( sText, "Usage", nBuf );
|
||||
|
||||
nLen += StringCat( sText, CHC_DEFAULT, nBuf );
|
||||
nLen += StringCat( sText, ": " , nBuf );
|
||||
|
||||
nLen += StringCat( sText, CHC_ARG_OPT, nBuf );
|
||||
nLen += StringCat( sText, "[ ", nBuf );
|
||||
|
||||
nLen += StringCat( sText, CHC_ARG_MAND, nBuf );
|
||||
nLen += StringCat( sText, "< ", nBuf );
|
||||
std::string sText = CHC_USAGE "Usage" CHC_DEFAULT ": " CHC_ARG_OPT "[ " CHC_ARG_MAND "< ";
|
||||
|
||||
for (int iCategory = _PARAM_HELPCATEGORIES_BEGIN ; iCategory < _PARAM_HELPCATEGORIES_END; iCategory++)
|
||||
{
|
||||
char *pName = g_aParameters[ iCategory ].m_sName;
|
||||
const char *pName = g_aParameters[ iCategory ].m_sName;
|
||||
|
||||
if (nLen + strlen( pName ) >= (CONSOLE_WIDTH - 1))
|
||||
if (sText.length() + strlen(pName) >= (CONSOLE_WIDTH - 1))
|
||||
{
|
||||
ConsolePrint( sText );
|
||||
sText[ 0 ] = 0;
|
||||
nLen = StringCat( sText, " ", nBuf ); // indent
|
||||
ConsolePrint( sText.c_str() );
|
||||
sText = " "; // indent
|
||||
}
|
||||
|
||||
StringCat( sText, CHC_COMMAND, nBuf );
|
||||
nLen += StringCat( sText, pName , nBuf );
|
||||
sText += CHC_COMMAND;
|
||||
sText += pName;
|
||||
|
||||
if (iCategory < (_PARAM_HELPCATEGORIES_END - 1))
|
||||
{
|
||||
char sSep[] = " | ";
|
||||
const char sSep[] = " | ";
|
||||
|
||||
if (nLen + strlen( sSep ) >= (CONSOLE_WIDTH - 1))
|
||||
if (sText.length() + strlen(sSep) >= (CONSOLE_WIDTH - 1))
|
||||
{
|
||||
ConsolePrint( sText );
|
||||
sText[ 0 ] = 0;
|
||||
nLen = StringCat( sText, " ", nBuf ); // indent
|
||||
ConsolePrint( sText.c_str() );
|
||||
sText = " "; // indent
|
||||
}
|
||||
StringCat( sText, CHC_ARG_SEP, nBuf );
|
||||
nLen += StringCat( sText, sSep, nBuf );
|
||||
|
||||
sText += CHC_ARG_SEP;
|
||||
sText += sSep;
|
||||
}
|
||||
}
|
||||
|
||||
StringCat( sText, CHC_ARG_MAND, nBuf );
|
||||
StringCat( sText, " >", nBuf);
|
||||
sText += CHC_ARG_MAND " >" CHC_ARG_OPT " ]";
|
||||
|
||||
StringCat( sText, CHC_ARG_OPT, nBuf );
|
||||
StringCat( sText, " ]", nBuf);
|
||||
|
||||
// ConsoleBufferPush( sText );
|
||||
ConsolePrint( sText ); // Transcode colored text to native console color text
|
||||
// ConsoleBufferPush( sText.c_str() );
|
||||
ConsolePrint( sText.c_str() ); // Transcode colored text to native console color text
|
||||
|
||||
ConsolePrintFormat( "%sNotes%s: %s<>%s = mandatory, %s[]%s = optional, %s|%s argument option"
|
||||
, CHC_USAGE
|
||||
, CHC_DEFAULT
|
||||
, CHC_ARG_MAND
|
||||
, CHC_DEFAULT
|
||||
, CHC_ARG_OPT
|
||||
, CHC_DEFAULT
|
||||
, CHC_ARG_SEP
|
||||
, CHC_DEFAULT
|
||||
);
|
||||
// ConsoleBufferPush( sText );
|
||||
ConsolePrintFormat( CHC_USAGE "Notes" CHC_DEFAULT ": "
|
||||
CHC_ARG_MAND "<>" CHC_DEFAULT " = mandatory, "
|
||||
CHC_ARG_OPT "[]" CHC_DEFAULT " = optional, "
|
||||
CHC_ARG_SEP "|" CHC_DEFAULT " argument option" );
|
||||
// ConsoleBufferPush( sText.c_str() );
|
||||
}
|
||||
|
||||
void Help_Examples()
|
||||
|
@ -249,29 +164,26 @@ void Help_Operators()
|
|||
ConsolePrintFormat( " %s#%s Designate number in hex" , CHC_USAGE, CHC_DEFAULT );
|
||||
// ConsoleBufferPush( " Operators: (Range)" );
|
||||
ConsolePrintFormat( " Operators: (%sRange%s)" , CHC_USAGE, CHC_DEFAULT );
|
||||
ConsolePrintFormat( " %s,%s range seperator (2nd address is relative)", CHC_USAGE, CHC_DEFAULT );
|
||||
ConsolePrintFormat( " %s:%s range seperator (2nd address is absolute)", CHC_USAGE, CHC_DEFAULT );
|
||||
ConsolePrintFormat( " %s,%s range separator (2nd address is relative)", CHC_USAGE, CHC_DEFAULT );
|
||||
ConsolePrintFormat( " %s:%s range separator (2nd address is absolute)", CHC_USAGE, CHC_DEFAULT );
|
||||
// ConsolePrintFormat( " Operators: (Misc)" );
|
||||
ConsolePrintFormat( " Operators: (%sMisc%s)" , CHC_USAGE, CHC_DEFAULT );
|
||||
ConsolePrintFormat( " %s//%s comment until end of line" , CHC_USAGE, CHC_DEFAULT );
|
||||
// ConsoleBufferPush( " Operators: (Breakpoint)" );
|
||||
ConsolePrintFormat( " Operators: (%sBreakpoint%s)" , CHC_USAGE, CHC_DEFAULT );
|
||||
|
||||
char sText[CONSOLE_WIDTH];
|
||||
_tcscpy( sText, " " );
|
||||
strcat( sText, CHC_USAGE );
|
||||
int iBreakOp = 0;
|
||||
for( iBreakOp = 0; iBreakOp < NUM_BREAKPOINT_OPERATORS; iBreakOp++ )
|
||||
std::string sText = " " CHC_USAGE;
|
||||
for ( int iBreakOp = 0; iBreakOp < NUM_BREAKPOINT_OPERATORS; iBreakOp++ )
|
||||
{
|
||||
if ((iBreakOp >= PARAM_BP_LESS_EQUAL) &&
|
||||
(iBreakOp <= PARAM_BP_GREATER_EQUAL))
|
||||
{
|
||||
strcat( sText, g_aBreakpointSymbols[ iBreakOp ] );
|
||||
strcat( sText, " " );
|
||||
sText += g_aBreakpointSymbols[ iBreakOp ];
|
||||
sText += ' ';
|
||||
}
|
||||
}
|
||||
strcat( sText, CHC_DEFAULT );
|
||||
ConsolePrint( sText );
|
||||
sText += CHC_DEFAULT;
|
||||
ConsolePrint( sText.c_str() );
|
||||
}
|
||||
|
||||
void Help_KeyboardShortcuts()
|
||||
|
@ -452,7 +364,7 @@ bool Colorize( char * pDst, size_t /*nDstSz*/, const char* pSrc)
|
|||
const char *start = pSrc;
|
||||
const char *end = pSrc;
|
||||
|
||||
while( isHexDigit( *end ) )
|
||||
while ( isHexDigit( *end ) )
|
||||
end++;
|
||||
|
||||
size_t nDigits = end - start;
|
||||
|
@ -580,11 +492,11 @@ Update_t CmdHelpSpecific (int nArgs)
|
|||
{
|
||||
// int nFoundCategory = FindParam( g_aArgs[ iArg ].sArg, MATCH_EXACT, iParam, _PARAM_HELPCATEGORIES_BEGIN, _PARAM_HELPCATEGORIES_END );
|
||||
int nFoundCategory = FindParam( g_aArgs[ iArg ].sArg, MATCH_FUZZY, iParam, _PARAM_HELPCATEGORIES_BEGIN, _PARAM_HELPCATEGORIES_END );
|
||||
if( nFoundCategory )
|
||||
if ( nFoundCategory )
|
||||
bCategory = true;
|
||||
else
|
||||
bCategory = false;
|
||||
switch( iParam )
|
||||
switch ( iParam )
|
||||
{
|
||||
case PARAM_CAT_BOOKMARKS : iCmdBegin = CMD_BOOKMARK ; iCmdEnd = CMD_BOOKMARK_SAVE ; break;
|
||||
case PARAM_CAT_BREAKPOINTS: iCmdBegin = CMD_BREAK_INVALID ; iCmdEnd = CMD_BREAKPOINT_SAVE ; break;
|
||||
|
@ -646,7 +558,7 @@ Update_t CmdHelpSpecific (int nArgs)
|
|||
if (nFound) {
|
||||
bCategory = false;
|
||||
} else // 2.7.0.17: HELP <category> wasn't displaying when category was one of: FLAGS, OUTPUT, WATCHES
|
||||
if( nFoundCategory )
|
||||
if ( nFoundCategory )
|
||||
{
|
||||
iCmdBegin = CMD_WATCH_ADD ; iCmdEnd = CMD_WATCH_LIST ;
|
||||
}
|
||||
|
@ -735,62 +647,62 @@ Update_t CmdHelpSpecific (int nArgs)
|
|||
// if (nFound && (! bAllCommands) && (! bCategory))
|
||||
if (nFound && (! bAllCommands) && bDisplayCategory)
|
||||
{
|
||||
const char* pszCategory = "";
|
||||
const char* pCategory = "";
|
||||
int iCmd = g_aCommands[ iCommand ].iCommand; // Unaliased command
|
||||
|
||||
// HACK: Major kludge to display category!!!
|
||||
if (iCmd <= CMD_UNASSEMBLE)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_CPU ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_CPU ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_BOOKMARK_SAVE)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_BOOKMARKS ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_BOOKMARKS ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_BREAKPOINT_SAVE)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_BREAKPOINTS ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_BREAKPOINTS ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_CONFIG_SET_DEBUG_DIR)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_CONFIG ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_CONFIG ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_CURSOR_PAGE_DOWN_4K)
|
||||
pszCategory = "Scrolling";
|
||||
pCategory = "Scrolling";
|
||||
else
|
||||
if (iCmd <= CMD_FLAG_SET_N)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_FLAGS ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_FLAGS ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_MOTD)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_HELP ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_HELP ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_MEMORY_FILL)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_MEMORY ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_MEMORY ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_OUTPUT_RUN)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_OUTPUT ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_OUTPUT ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_SYNC)
|
||||
pszCategory = "Source";
|
||||
pCategory = "Source";
|
||||
else
|
||||
if (iCmd <= CMD_SYMBOLS_LIST)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_SYMBOLS ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_SYMBOLS ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_VIEW_DHGR2)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_VIEW ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_VIEW ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_WATCH_SAVE)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_WATCHES ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_WATCHES ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_WINDOW_OUTPUT)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_WINDOW ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_WINDOW ].m_sName;
|
||||
else
|
||||
if (iCmd <= CMD_ZEROPAGE_POINTER_SAVE)
|
||||
pszCategory = g_aParameters[ PARAM_CAT_ZEROPAGE ].m_sName;
|
||||
pCategory = g_aParameters[ PARAM_CAT_ZEROPAGE ].m_sName;
|
||||
else
|
||||
pszCategory = "Unknown!";
|
||||
pCategory = "Unknown!";
|
||||
|
||||
ConsolePrintFormat( "%sCategory%s: %s%s"
|
||||
, CHC_USAGE
|
||||
, CHC_DEFAULT
|
||||
, CHC_CATEGORY
|
||||
, pszCategory );
|
||||
, pCategory );
|
||||
|
||||
if (bCategory)
|
||||
bDisplayCategory = false;
|
||||
|
@ -801,8 +713,8 @@ Update_t CmdHelpSpecific (int nArgs)
|
|||
const char *const pHelp = pCommand->pHelpSummary;
|
||||
if (pHelp)
|
||||
{
|
||||
std::string strText = StrFormat((bCategory) ? "%s%8s%s%s%s, "
|
||||
: "%s%s%s%s%s, ",
|
||||
std::string strText = StrFormat((bCategory) ? "%s%8s%s, %s%s"
|
||||
: "%s%s%s, %s%s",
|
||||
CHC_COMMAND, pCommand->m_sName, CHC_ARG_SEP,
|
||||
CHC_DEFAULT, pHelp);
|
||||
//ConsoleBufferPush( strText.c_str() );
|
||||
|
@ -937,15 +849,17 @@ Update_t CmdHelpSpecific (int nArgs)
|
|||
break;
|
||||
// Breakpoints
|
||||
case CMD_BREAK_INVALID:
|
||||
ConsoleColorizePrintFormat( " Usage: [%s%s | %s%s] | [# | # %s%s | # %s%s]"
|
||||
ConsoleColorizePrintFormat( " Usage: [%s%s | %s%s]"
|
||||
, CHC_COMMAND
|
||||
, g_aParameters[ PARAM_ON ].m_sName
|
||||
, g_aParameters[PARAM_ON].m_sName
|
||||
, CHC_COMMAND
|
||||
, g_aParameters[ PARAM_OFF ].m_sName
|
||||
, g_aParameters[PARAM_OFF].m_sName
|
||||
);
|
||||
ConsoleColorizePrintFormat(" Usage: [# | # %s%s | # %s%s]"
|
||||
, CHC_COMMAND
|
||||
, g_aParameters[ PARAM_ON ].m_sName
|
||||
, g_aParameters[PARAM_ON].m_sName
|
||||
, CHC_COMMAND
|
||||
, g_aParameters[ PARAM_OFF ].m_sName
|
||||
, g_aParameters[PARAM_OFF].m_sName
|
||||
);
|
||||
ConsoleColorizePrintFormat( " Usage: [%s%s %s%s | %s%s %s%s]"
|
||||
, CHC_COMMAND
|
||||
|
@ -1026,7 +940,10 @@ Update_t CmdHelpSpecific (int nArgs)
|
|||
ConsoleColorizePrint( " Usage: <range>" );
|
||||
Help_Range();
|
||||
break;
|
||||
// Config - Load / Save
|
||||
case CMD_BREAKPOINT_ADD_VIDEO:
|
||||
ConsoleColorizePrint( " Usage: <vpos[,length]>" );
|
||||
break;
|
||||
// Config - Load / Save
|
||||
case CMD_CONFIG_LOAD:
|
||||
ConsoleColorizePrint( " Usage: [\"filename\"]" );
|
||||
ConsoleBufferPushFormat( " Load debugger configuration from '%s', or the specificed file.", g_sFileNameConfig.c_str() );
|
||||
|
@ -1485,33 +1402,23 @@ Update_t CmdHelpSpecific (int nArgs)
|
|||
//===========================================================================
|
||||
Update_t CmdHelpList (int nArgs)
|
||||
{
|
||||
const int nBuf = CONSOLE_WIDTH * 2;
|
||||
|
||||
char sText[ nBuf ] = "";
|
||||
|
||||
int nMaxWidth = g_nConsoleDisplayWidth - 1;
|
||||
int iCommand;
|
||||
const size_t nMaxWidth = g_nConsoleDisplayWidth - 1;
|
||||
|
||||
extern std::vector<Command_t> g_vSortedCommands;
|
||||
|
||||
if (! g_vSortedCommands.size())
|
||||
{
|
||||
for (iCommand = 0; iCommand < NUM_COMMANDS_WITH_ALIASES; iCommand++ )
|
||||
for ( int iCommand = 0; iCommand < NUM_COMMANDS_WITH_ALIASES; iCommand++ )
|
||||
{
|
||||
g_vSortedCommands.push_back( g_aCommands[ iCommand ] );
|
||||
}
|
||||
std::sort( g_vSortedCommands.begin(), g_vSortedCommands.end(), commands_functor_compare() );
|
||||
}
|
||||
|
||||
int nLen = 0;
|
||||
// Colorize( sText, "Commands: " );
|
||||
StringCat( sText, CHC_USAGE , nBuf );
|
||||
nLen += StringCat( sText, "Commands", nBuf );
|
||||
//Colorize( sText, "Commands: " );
|
||||
std::string sText = CHC_USAGE "Commands" CHC_DEFAULT ": ";
|
||||
|
||||
StringCat( sText, CHC_DEFAULT, nBuf );
|
||||
nLen += StringCat( sText, ": " , nBuf );
|
||||
|
||||
for( iCommand = 0; iCommand < NUM_COMMANDS_WITH_ALIASES; iCommand++ ) // aliases are not printed
|
||||
for ( int iCommand = 0; iCommand < NUM_COMMANDS_WITH_ALIASES; iCommand++ ) // aliases are not printed
|
||||
{
|
||||
Command_t *pCommand = & g_vSortedCommands.at( iCommand );
|
||||
// Command_t *pCommand = & g_aCommands[ iCommand ];
|
||||
|
@ -1520,27 +1427,22 @@ Update_t CmdHelpList (int nArgs)
|
|||
if (! pCommand->pFunction)
|
||||
continue; // not implemented function
|
||||
|
||||
int nLenCmd = strlen( pName );
|
||||
if ((nLen + nLenCmd) < (nMaxWidth))
|
||||
if ((sText.length() + strlen(pName)) < nMaxWidth)
|
||||
{
|
||||
StringCat( sText, CHC_COMMAND, nBuf );
|
||||
nLen += StringCat( sText, pName , nBuf );
|
||||
sText += CHC_COMMAND;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsolePrint( sText );
|
||||
nLen = 1;
|
||||
strcpy( sText, " " );
|
||||
StringCat( sText, CHC_COMMAND, nBuf );
|
||||
nLen += StringCat( sText, pName, nBuf );
|
||||
ConsolePrint( sText.c_str() );
|
||||
sText = " " CHC_COMMAND;
|
||||
}
|
||||
sText += pName;
|
||||
|
||||
strcat( sText, " " );
|
||||
nLen++;
|
||||
sText += ' ';
|
||||
}
|
||||
|
||||
//ConsoleBufferPush( sText );
|
||||
ConsolePrint( sText );
|
||||
//ConsoleBufferPush( sText.c_str() );
|
||||
ConsolePrint( sText.c_str() );
|
||||
ConsoleUpdate();
|
||||
|
||||
return UPDATE_CONSOLE_DISPLAY;
|
||||
|
|
|
@ -26,8 +26,4 @@ inline void UnpackVersion( const unsigned int nVersion,
|
|||
nFixMinor_ = (nVersion >> 0) & 0xFF;
|
||||
}
|
||||
|
||||
bool TestStringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize );
|
||||
bool TryStringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize );
|
||||
int StringCat( TCHAR * pDst, LPCSTR pSrc, const int nDstSize );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -286,7 +286,7 @@ int ArgsGet ( TCHAR * pInput )
|
|||
|
||||
if (iTokenSrc == TOKEN_SEMI)
|
||||
{
|
||||
// TODO - command seperator, must handle non-quoted though!
|
||||
// TODO - command separator, must handle non-quoted though!
|
||||
}
|
||||
|
||||
if (iTokenSrc == TOKEN_QUOTE_DOUBLE)
|
||||
|
@ -366,7 +366,7 @@ bool ArgsGetRegisterValue ( Arg_t *pArg, WORD * pAddressValue_ )
|
|||
if (pArg && pAddressValue_)
|
||||
{
|
||||
// Check if we refer to reg A X Y P S
|
||||
for( int iReg = 0; iReg < (NUM_BREAKPOINT_SOURCES-1); iReg++ )
|
||||
for ( int iReg = 0; iReg < (NUM_BREAKPOINT_SOURCES-1); iReg++ )
|
||||
{
|
||||
// Skip Opcode/Instruction/Mnemonic
|
||||
if (iReg == BP_SRC_OPCODE)
|
||||
|
@ -379,7 +379,7 @@ bool ArgsGetRegisterValue ( Arg_t *pArg, WORD * pAddressValue_ )
|
|||
// Handle one char names
|
||||
if ((pArg->nArgLen == 1) && (pArg->sArg[0] == g_aBreakpointSource[ iReg ][0]))
|
||||
{
|
||||
switch( iReg )
|
||||
switch ( iReg )
|
||||
{
|
||||
case BP_SRC_REG_A : *pAddressValue_ = regs.a & 0xFF; bStatus = true; break;
|
||||
case BP_SRC_REG_P : *pAddressValue_ = regs.ps & 0xFF; bStatus = true; break;
|
||||
|
@ -912,7 +912,7 @@ void TextConvertTabsToSpaces( TCHAR *pDeTabified_, LPCTSTR pText, const int nDst
|
|||
if ((nCur + nGap) >= nDstSize)
|
||||
break;
|
||||
|
||||
for( int iSpc = 0; iSpc < nGap; iSpc++ )
|
||||
for ( int iSpc = 0; iSpc < nGap; iSpc++ )
|
||||
{
|
||||
*pDst++ = CHAR_SPACE;
|
||||
}
|
||||
|
|
|
@ -75,9 +75,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
// Utils _ ________________________________________________________________________________________
|
||||
|
||||
void _CmdSymbolsInfoHeader( int iTable, char * pText, int nDisplaySize = 0 );
|
||||
void _PrintCurrentPath();
|
||||
Update_t _PrintSymbolInvalidTable();
|
||||
std::string _CmdSymbolsInfoHeader( int iTable, int nDisplaySize = 0 );
|
||||
void _PrintCurrentPath();
|
||||
Update_t _PrintSymbolInvalidTable();
|
||||
|
||||
|
||||
// Private ________________________________________________________________________________________
|
||||
|
@ -90,33 +90,28 @@ void _PrintCurrentPath()
|
|||
|
||||
Update_t _PrintSymbolInvalidTable()
|
||||
{
|
||||
char sText[ CONSOLE_WIDTH * 2 ];
|
||||
char sTemp[ CONSOLE_WIDTH * 2 ];
|
||||
|
||||
// TODO: display the user specified file name
|
||||
ConsoleBufferPush( "Invalid symbol table." );
|
||||
|
||||
ConsolePrintFormat( "Only %s%d%s symbol tables are supported:"
|
||||
, CHC_NUM_DEC, NUM_SYMBOL_TABLES
|
||||
, CHC_DEFAULT
|
||||
ConsolePrintFormat( "Only " CHC_NUM_DEC "%d" CHC_DEFAULT " symbol tables are supported:"
|
||||
, NUM_SYMBOL_TABLES
|
||||
);
|
||||
|
||||
std::string sText;
|
||||
|
||||
// Similar to _CmdSymbolsInfoHeader()
|
||||
sText[0] = 0;
|
||||
for( int iTable = 0; iTable < NUM_SYMBOL_TABLES; iTable++ )
|
||||
for ( int iTable = 0; iTable < NUM_SYMBOL_TABLES; iTable++ )
|
||||
{
|
||||
sprintf( sTemp, "%s%s%s%c " // %s"
|
||||
, CHC_USAGE, g_aSymbolTableNames[ iTable ]
|
||||
, CHC_ARG_SEP
|
||||
sText += StrFormat( CHC_USAGE "%s" CHC_ARG_SEP "%c "
|
||||
, g_aSymbolTableNames[ iTable ]
|
||||
, (iTable != (NUM_SYMBOL_TABLES-1))
|
||||
? ','
|
||||
: '.'
|
||||
);
|
||||
strcat( sText, sTemp );
|
||||
}
|
||||
|
||||
// return ConsoleDisplayError( sText );
|
||||
ConsolePrint( sText );
|
||||
// return ConsoleDisplayError( sText.c_str() );
|
||||
ConsolePrint( sText.c_str() );
|
||||
return ConsoleUpdate();
|
||||
}
|
||||
|
||||
|
@ -125,13 +120,13 @@ Update_t _PrintSymbolInvalidTable()
|
|||
|
||||
|
||||
//===========================================================================
|
||||
std::string const& GetSymbol (WORD nAddress, int nBytes, std::string& strAddressBuf)
|
||||
std::string const& GetSymbol (WORD nAddress, int nBytes, std::string& sAddressBuf)
|
||||
{
|
||||
std::string const* pSymbol = FindSymbolFromAddress( nAddress );
|
||||
if (pSymbol)
|
||||
return *pSymbol;
|
||||
|
||||
return strAddressBuf = FormatAddress( nAddress, nBytes );
|
||||
return sAddressBuf = FormatAddress( nAddress, nBytes );
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -160,7 +155,7 @@ std::string const* FindSymbolFromAddress (WORD nAddress, int * iTable_ )
|
|||
continue;
|
||||
|
||||
std::map<WORD, std::string>::iterator iSymbols = g_aSymbols[iTable].find(nAddress);
|
||||
if(g_aSymbols[iTable].find(nAddress) != g_aSymbols[iTable].end())
|
||||
if (g_aSymbols[iTable].find(nAddress) != g_aSymbols[iTable].end())
|
||||
{
|
||||
if (iTable_)
|
||||
{
|
||||
|
@ -286,7 +281,7 @@ Update_t CmdSymbolsClear (int nArgs)
|
|||
|
||||
// Format the summary of the specified symbol table
|
||||
//===========================================================================
|
||||
void _CmdSymbolsInfoHeader( int iTable, char * pText, int nDisplaySize /* = 0 */ )
|
||||
std::string _CmdSymbolsInfoHeader( int iTable, int nDisplaySize /* = 0 */ )
|
||||
{
|
||||
// Common case is to use/calc the table size
|
||||
bool bActive = (g_bDisplaySymbolTables & (1 << iTable)) ? true : false;
|
||||
|
@ -295,25 +290,17 @@ void _CmdSymbolsInfoHeader( int iTable, char * pText, int nDisplaySize /* = 0 */
|
|||
// Short Desc: `MAIN`: `1000`
|
||||
// // 2.6.2.19 Color for name of symbol table: _CmdPrintSymbol() "SYM HOME" _CmdSymbolsInfoHeader "SYM"
|
||||
// CHC_STRING and CHC_NUM_DEC are both cyan, using CHC_USAGE instead of CHC_STRING
|
||||
sprintf( pText, "%s%s%s:%s%d " // %s"
|
||||
, CHC_USAGE, g_aSymbolTableNames[ iTable ]
|
||||
, CHC_ARG_SEP
|
||||
return StrFormat(CHC_USAGE "%s" CHC_ARG_SEP ":%s%d " // CHC_DEFAULT
|
||||
, g_aSymbolTableNames[ iTable ]
|
||||
, bActive ? CHC_NUM_DEC : CHC_WARNING, nSymbols
|
||||
// , CHC_DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
Update_t CmdSymbolsInfo (int nArgs)
|
||||
{
|
||||
const char sIndent[] = " ";
|
||||
char sText[ CONSOLE_WIDTH * 4 ] = "";
|
||||
char sTemp[ CONSOLE_WIDTH * 2 ] = "";
|
||||
|
||||
int bDisplaySymbolTables = 0;
|
||||
|
||||
strcpy( sText, sIndent ); // Indent new line
|
||||
|
||||
if (! nArgs)
|
||||
{
|
||||
// default to all tables
|
||||
|
@ -333,26 +320,27 @@ Update_t CmdSymbolsInfo (int nArgs)
|
|||
//sprintf( sText, " Symbols Main: %s%d%s User: %s%d%s Source: %s%d%s"
|
||||
// "Main:# Basic:# Asm:# User1:# User2:# Src1:# Src2:# Dos:# Prodos:#
|
||||
|
||||
int bTable = 1;
|
||||
int iTable = 0;
|
||||
for( ; bTable <= bDisplaySymbolTables; iTable++, bTable <<= 1 )
|
||||
std::string const sIndent = " ";
|
||||
std::string sText = sIndent; // Indent new line
|
||||
|
||||
for ( int iTable = 0, bTable = 1; bTable <= bDisplaySymbolTables; iTable++, bTable <<= 1 )
|
||||
{
|
||||
if( bDisplaySymbolTables & bTable )
|
||||
if ( !!(bDisplaySymbolTables & bTable) )
|
||||
{
|
||||
_CmdSymbolsInfoHeader( iTable, sTemp ); // 15 chars per table
|
||||
std::string hdr = _CmdSymbolsInfoHeader( iTable ); // 15 chars per table
|
||||
|
||||
// 2.8.0.4 BUGFIX: Check for buffer overflow and wrap text
|
||||
int nLen = ConsoleColor_StringLength( sTemp );
|
||||
int nDst = ConsoleColor_StringLength( sText );
|
||||
if((nDst + nLen) > CONSOLE_WIDTH )
|
||||
int nLen = ConsoleColor_StringLength( hdr.c_str() );
|
||||
int nDst = ConsoleColor_StringLength( sText.c_str() );
|
||||
if ( (nDst + nLen) > CONSOLE_WIDTH )
|
||||
{
|
||||
ConsolePrint( sText );
|
||||
strcpy( sText, sIndent ); // Indent new line
|
||||
ConsolePrint( sText.c_str() );
|
||||
sText = sIndent; // Indent new line
|
||||
}
|
||||
strcat( sText, sTemp );
|
||||
sText += hdr;
|
||||
}
|
||||
}
|
||||
ConsolePrint( sText );
|
||||
ConsolePrint( sText.c_str() );
|
||||
|
||||
return ConsoleUpdate();
|
||||
}
|
||||
|
@ -381,7 +369,7 @@ bool _FindSymbolTable( int bSymbolTables, int iTable )
|
|||
// iTable is enumeration
|
||||
// bSymbolTables is bit-flags of enabled tables to search
|
||||
|
||||
if( bSymbolTables & (1 << iTable) )
|
||||
if ( bSymbolTables & (1 << iTable) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -396,9 +384,9 @@ int _GetSymbolTableFromFlag( int bSymbolTables )
|
|||
int iTable = 0;
|
||||
int bTable = 1;
|
||||
|
||||
for( ; bTable <= bSymbolTables; iTable++, bTable <<= 1 )
|
||||
for ( ; bTable <= bSymbolTables; iTable++, bTable <<= 1 )
|
||||
{
|
||||
if( bTable & bSymbolTables )
|
||||
if ( bTable & bSymbolTables )
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -475,25 +463,23 @@ Update_t _CmdSymbolsListTables (int nArgs, int bSymbolTables )
|
|||
SYMBOL B = $2000
|
||||
SYM B
|
||||
*/
|
||||
|
||||
TCHAR sText[ CONSOLE_WIDTH ] = "";
|
||||
|
||||
for( int iArgs = 1; iArgs <= nArgs; iArgs++ )
|
||||
for ( int iArgs = 1; iArgs <= nArgs; iArgs++ )
|
||||
{
|
||||
WORD nAddress = g_aArgs[iArgs].nValue;
|
||||
LPCTSTR pSymbol = g_aArgs[iArgs].sArg;
|
||||
|
||||
// Dump all symbols for this table
|
||||
if( g_aArgRaw[iArgs].eToken == TOKEN_STAR)
|
||||
if ( g_aArgRaw[iArgs].eToken == TOKEN_STAR)
|
||||
{
|
||||
// int iWhichTable = (g_iCommand - CMD_SYMBOLS_MAIN);
|
||||
// bDisplaySymbolTables = (1 << iWhichTable);
|
||||
|
||||
int iTable = 0;
|
||||
int bTable = 1;
|
||||
for( ; bTable <= bSymbolTables; iTable++, bTable <<= 1 )
|
||||
for ( ; bTable <= bSymbolTables; iTable++, bTable <<= 1 )
|
||||
{
|
||||
if( bTable & bSymbolTables )
|
||||
if ( bTable & bSymbolTables )
|
||||
{
|
||||
int nSymbols = g_aSymbols[iTable].size();
|
||||
if (nSymbols)
|
||||
|
@ -507,8 +493,7 @@ Update_t _CmdSymbolsListTables (int nArgs, int bSymbolTables )
|
|||
++iSymbol;
|
||||
}
|
||||
}
|
||||
_CmdSymbolsInfoHeader( iTable, sText );
|
||||
ConsolePrint( sText );
|
||||
ConsolePrint(_CmdSymbolsInfoHeader(iTable).c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -564,12 +549,12 @@ int ParseSymbolTable(const std::string & pPathFileName, SymbolTable_Index_e eSym
|
|||
if (pPathFileName.empty())
|
||||
return nSymbolsLoaded;
|
||||
|
||||
std::string strFormat1 = StrFormat( "%%x %%%ds", MAX_SYMBOLS_LEN ); // i.e. "%x %13s"
|
||||
std::string strFormat2 = StrFormat( "%%%ds %%x", MAX_SYMBOLS_LEN ); // i.e. "%13s %x"
|
||||
std::string sFormat1 = StrFormat( "%%x %%%ds", MAX_SYMBOLS_LEN ); // i.e. "%x %13s"
|
||||
std::string sFormat2 = StrFormat( "%%%ds %%x", MAX_SYMBOLS_LEN ); // i.e. "%13s %x"
|
||||
|
||||
FILE *hFile = fopen( pPathFileName.c_str(), "rt" );
|
||||
|
||||
if( !hFile && g_bSymbolsDisplayMissingFile )
|
||||
if ( !hFile && g_bSymbolsDisplayMissingFile )
|
||||
{
|
||||
// TODO: print filename! Bug #242 Help file (.chm) description for "Symbols" #242
|
||||
ConsoleDisplayError( "Symbol File not found:" );
|
||||
|
@ -578,9 +563,9 @@ int ParseSymbolTable(const std::string & pPathFileName, SymbolTable_Index_e eSym
|
|||
}
|
||||
|
||||
bool bDupSymbolHeader = false;
|
||||
if( hFile )
|
||||
if ( hFile )
|
||||
{
|
||||
while( !feof(hFile) )
|
||||
while ( !feof(hFile) )
|
||||
{
|
||||
// Support 2 types of symbols files:
|
||||
// 1) AppleWin:
|
||||
|
@ -596,24 +581,24 @@ int ParseSymbolTable(const std::string & pPathFileName, SymbolTable_Index_e eSym
|
|||
const int MAX_LINE = 256;
|
||||
char szLine[ MAX_LINE ] = "";
|
||||
|
||||
if( !fgets(szLine, MAX_LINE-1, hFile) ) // Get next line
|
||||
if ( !fgets(szLine, MAX_LINE-1, hFile) ) // Get next line
|
||||
{
|
||||
//ConsolePrint("<<EOF");
|
||||
break;
|
||||
}
|
||||
|
||||
if(strstr(szLine, "$") == NULL)
|
||||
if (strstr(szLine, "$") == NULL)
|
||||
{
|
||||
sscanf(szLine, strFormat1.c_str(), &nAddress, sName);
|
||||
sscanf(szLine, sFormat1.c_str(), &nAddress, sName);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* p = strstr(szLine, "="); // Optional
|
||||
if(p) *p = ' ';
|
||||
if (p) *p = ' ';
|
||||
p = strstr(szLine, "$");
|
||||
if(p) *p = ' ';
|
||||
if (p) *p = ' ';
|
||||
p = strstr(szLine, ";"); // Optional
|
||||
if(p) *p = 0;
|
||||
if (p) *p = 0;
|
||||
p = strstr(szLine, " "); // 1st space between name & value
|
||||
if (p)
|
||||
{
|
||||
|
@ -623,13 +608,13 @@ int ParseSymbolTable(const std::string & pPathFileName, SymbolTable_Index_e eSym
|
|||
memset(&szLine[MAX_SYMBOLS_LEN], ' ', nLen - MAX_SYMBOLS_LEN); // sscanf fails for nAddress if string too long
|
||||
}
|
||||
}
|
||||
sscanf(szLine, strFormat2.c_str(), sName, &nAddress);
|
||||
sscanf(szLine, sFormat2.c_str(), sName, &nAddress);
|
||||
}
|
||||
|
||||
// SymbolOffset
|
||||
nAddress += nSymbolOffset;
|
||||
|
||||
if( (nAddress > _6502_MEM_END) || (sName[0] == 0) )
|
||||
if ( (nAddress > _6502_MEM_END) || (sName[0] == 0) )
|
||||
continue;
|
||||
|
||||
// 2.9.0.11 Bug #479
|
||||
|
@ -655,9 +640,9 @@ int ParseSymbolTable(const std::string & pPathFileName, SymbolTable_Index_e eSym
|
|||
|
||||
// 2.8.0.5 Bug #244 (Debugger) Duplicate symbols for identical memory addresses in APPLE2E.SYM
|
||||
std::string const* pSymbolPrev = FindSymbolFromAddress( (WORD)nAddress, &iTable ); // don't care which table it is in
|
||||
if( pSymbolPrev )
|
||||
if ( pSymbolPrev )
|
||||
{
|
||||
if( !bFileDisplayed )
|
||||
if ( !bFileDisplayed )
|
||||
{
|
||||
bFileDisplayed = true;
|
||||
|
||||
|
@ -712,9 +697,9 @@ int ParseSymbolTable(const std::string & pPathFileName, SymbolTable_Index_e eSym
|
|||
WORD nAddressPrev = 0;
|
||||
|
||||
bool bExists = FindAddressFromSymbol( sName, &nAddressPrev, &iTable );
|
||||
if( bExists )
|
||||
if ( bExists )
|
||||
{
|
||||
if( !bDupSymbolHeader )
|
||||
if ( !bDupSymbolHeader )
|
||||
{
|
||||
bDupSymbolHeader = true;
|
||||
ConsolePrintFormat( " %sDup Symbol Name%s (%s%s%s) %s"
|
||||
|
@ -773,7 +758,7 @@ Update_t CmdSymbolsLoad (int nArgs)
|
|||
{
|
||||
std::string pFileName;
|
||||
|
||||
if( g_aArgs[ iArg ].bType & TYPE_QUOTED_2 )
|
||||
if ( g_aArgs[ iArg ].bType & TYPE_QUOTED_2 )
|
||||
{
|
||||
pFileName = g_aArgs[ iArg ].sArg;
|
||||
|
||||
|
@ -788,15 +773,15 @@ Update_t CmdSymbolsLoad (int nArgs)
|
|||
unsigned int nOffsetAddr = 0;
|
||||
|
||||
iArg++;
|
||||
if( iArg <= nArgs)
|
||||
if ( iArg <= nArgs)
|
||||
{
|
||||
if (g_aArgs[ iArg ].eToken == TOKEN_COMMA)
|
||||
{
|
||||
iArg++;
|
||||
if( iArg <= nArgs )
|
||||
if ( iArg <= nArgs )
|
||||
{
|
||||
nOffsetAddr = g_aArgs[ iArg ].nValue;
|
||||
if( (nOffsetAddr < _6502_MEM_BEGIN) || (nOffsetAddr > _6502_MEM_END) )
|
||||
if ( (nOffsetAddr < _6502_MEM_BEGIN) || (nOffsetAddr > _6502_MEM_END) )
|
||||
{
|
||||
nOffsetAddr = 0;
|
||||
}
|
||||
|
@ -804,13 +789,13 @@ Update_t CmdSymbolsLoad (int nArgs)
|
|||
}
|
||||
}
|
||||
|
||||
if( !pFileName.empty() )
|
||||
if ( !pFileName.empty() )
|
||||
{
|
||||
nSymbols = ParseSymbolTable( sFileName, (SymbolTable_Index_e) iSymbolTable, nOffsetAddr );
|
||||
}
|
||||
}
|
||||
|
||||
if( nSymbols > 0 )
|
||||
if ( nSymbols > 0 )
|
||||
{
|
||||
g_nSymbolsLoaded = nSymbols;
|
||||
}
|
||||
|
@ -926,7 +911,7 @@ Update_t _CmdSymbolsUpdate( int nArgs, int bSymbolTables )
|
|||
bSymbolTables = SYMBOL_TABLE_USER_2; // Autogenerated symbol names go in table 2 for organization when reverse engineering. Table 1 = known, Table 2 = unknown.
|
||||
|
||||
nAddress = g_aArgs[2].nValue;
|
||||
sprintf( g_aArgs[1].sArg, "_%04X", nAddress ); // Autogenerated symbol name
|
||||
strncpy_s( g_aArgs[1].sArg, StrFormat("_%04X", nAddress).c_str(), _TRUNCATE ); // Autogenerated symbol name
|
||||
|
||||
bUpdateSymbol = true;
|
||||
}
|
||||
|
@ -954,8 +939,6 @@ Update_t _CmdSymbolsCommon ( int nArgs, int bSymbolTables )
|
|||
if (iUpdate != UPDATE_NOTHING)
|
||||
return iUpdate;
|
||||
|
||||
TCHAR sText[ CONSOLE_WIDTH ];
|
||||
|
||||
int iArg = 0;
|
||||
while (iArg++ <= nArgs)
|
||||
{
|
||||
|
@ -992,15 +975,9 @@ Update_t _CmdSymbolsCommon ( int nArgs, int bSymbolTables )
|
|||
int iTable = _GetSymbolTableFromFlag( bSymbolTables );
|
||||
if (iTable != NUM_SYMBOL_TABLES)
|
||||
{
|
||||
if( bUpdate & UPDATE_SYMBOLS )
|
||||
if ( bUpdate & UPDATE_SYMBOLS )
|
||||
{
|
||||
//sprintf( sText, " Symbol Table: %s%s%s, %sloaded symbols: %s%d"
|
||||
// , CHC_STRING, g_aSymbolTableNames[ iTable ]
|
||||
// , CHC_DEFAULT, CHC_DEFAULT
|
||||
// , CHC_NUM_DEC, g_nSymbolsLoaded
|
||||
//);
|
||||
_CmdSymbolsInfoHeader( iTable, sText, g_nSymbolsLoaded );
|
||||
ConsolePrint( sText );
|
||||
ConsolePrint( _CmdSymbolsInfoHeader( iTable, g_nSymbolsLoaded ).c_str() );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1022,8 +999,7 @@ Update_t _CmdSymbolsCommon ( int nArgs, int bSymbolTables )
|
|||
int iTable = _GetSymbolTableFromFlag( bSymbolTables );
|
||||
if (iTable != NUM_SYMBOL_TABLES)
|
||||
{
|
||||
_CmdSymbolsInfoHeader( iTable, sText );
|
||||
ConsolePrint( sText );
|
||||
ConsolePrint( _CmdSymbolsInfoHeader( iTable ).c_str() );
|
||||
}
|
||||
return ConsoleUpdate() | UPDATE_DISASM;
|
||||
}
|
||||
|
@ -1034,8 +1010,7 @@ Update_t _CmdSymbolsCommon ( int nArgs, int bSymbolTables )
|
|||
int iTable = _GetSymbolTableFromFlag( bSymbolTables );
|
||||
if (iTable != NUM_SYMBOL_TABLES)
|
||||
{
|
||||
_CmdSymbolsInfoHeader( iTable, sText );
|
||||
ConsolePrint( sText );
|
||||
ConsolePrint( _CmdSymbolsInfoHeader( iTable ).c_str() );
|
||||
}
|
||||
return ConsoleUpdate() | UPDATE_DISASM;
|
||||
}
|
||||
|
|
|
@ -183,6 +183,7 @@
|
|||
BP_SRC_MEM_RW,
|
||||
BP_SRC_MEM_READ_ONLY,
|
||||
BP_SRC_MEM_WRITE_ONLY,
|
||||
BP_SRC_VIDEO_SCANNER,
|
||||
|
||||
NUM_BREAKPOINT_SOURCES
|
||||
};
|
||||
|
@ -334,6 +335,7 @@
|
|||
, CMD_BREAKPOINT_ADD_MEM // break on: [$0000-$FFFF], excluding IO
|
||||
, CMD_BREAKPOINT_ADD_MEMR // break on read on: [$0000-$FFFF], excluding IO
|
||||
, CMD_BREAKPOINT_ADD_MEMW // break on write on: [$0000-$FFFF], excluding IO
|
||||
, CMD_BREAKPOINT_ADD_VIDEO // break on video scanner position
|
||||
|
||||
, CMD_BREAKPOINT_CLEAR
|
||||
// , CMD_BREAKPOINT_REMOVE = CMD_BREAKPOINT_CLEAR // alias
|
||||
|
@ -516,7 +518,7 @@
|
|||
, CMD_VIEW_DHGR2
|
||||
, CMD_VIEW_SHR
|
||||
// Watch
|
||||
, CMD_WATCH // TODO: Deprecated ?
|
||||
, CMD_WATCH
|
||||
, CMD_WATCH_ADD
|
||||
, CMD_WATCH_CLEAR
|
||||
, CMD_WATCH_DISABLE
|
||||
|
@ -641,6 +643,7 @@
|
|||
Update_t CmdBreakpointAddMemA (int nArgs);
|
||||
Update_t CmdBreakpointAddMemR (int nArgs);
|
||||
Update_t CmdBreakpointAddMemW (int nArgs);
|
||||
Update_t CmdBreakpointAddVideo (int nArgs);
|
||||
Update_t CmdBreakpointClear (int nArgs);
|
||||
Update_t CmdBreakpointDisable (int nArgs);
|
||||
Update_t CmdBreakpointEdit (int nArgs);
|
||||
|
@ -1271,7 +1274,7 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data
|
|||
, TOKEN_PLUS // + Delta Argument1 += Argument2
|
||||
, TOKEN_QUOTE_SINGLE // '
|
||||
, TOKEN_QUOTE_DOUBLE // "
|
||||
, TOKEN_SEMI // ; Command Seperator
|
||||
, TOKEN_SEMI // ; Command Separator
|
||||
, TOKEN_SPACE // Token Delimiter
|
||||
, TOKEN_STAR // *
|
||||
// , TOKEN_TAB // '\t'
|
||||
|
@ -1393,8 +1396,9 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data
|
|||
|
||||
// Disk
|
||||
, _PARAM_DISK_BEGIN = _PARAM_CONFIG_END // Daisy Chain
|
||||
, PARAM_DISK_EJECT = _PARAM_DISK_BEGIN // DISK 1 EJECT
|
||||
, PARAM_DISK_INFO // DISK 1 INFO
|
||||
, PARAM_DISK_INFO = _PARAM_DISK_BEGIN // DISK INFO
|
||||
, PARAM_DISK_SET_SLOT // DISK SLOT 6
|
||||
, PARAM_DISK_EJECT // DISK 1 EJECT
|
||||
, PARAM_DISK_PROTECT // DISK 1 PROTECT
|
||||
, PARAM_DISK_READ // DISK 1 READ Track Sector NumSectors MemAddress
|
||||
, _PARAM_DISK_END
|
||||
|
|
|
@ -339,7 +339,8 @@ void DebuggerMouseClick(int x, int y)
|
|||
|
||||
// do picking
|
||||
|
||||
const int nOffsetX = win32Frame.IsFullScreen() ? win32Frame.GetFullScreenOffsetX() : win32Frame.Get3DBorderWidth();
|
||||
// NB. Full-screen + VidHD isn't centred yet
|
||||
const int nOffsetX = win32Frame.IsFullScreen() ? win32Frame.GetFullScreenOffsetX() : win32Frame.Get3DBorderWidth() + GetVideo().GetFrameBufferCentringOffsetX() * win32Frame.GetViewportScale();
|
||||
const int nOffsetY = win32Frame.IsFullScreen() ? win32Frame.GetFullScreenOffsetY() : win32Frame.Get3DBorderHeight();
|
||||
|
||||
const int nOffsetInScreenX = x - nOffsetX;
|
||||
|
|
|
@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#include "Util_Text.h"
|
||||
#include "Util_MemoryTextFile.h"
|
||||
#include "StrFormat.h"
|
||||
|
||||
// MemoryTextFile _________________________________________________________________________________
|
||||
|
||||
|
@ -121,9 +122,9 @@ void MemoryTextFile_t::GetLinePointers()
|
|||
|
||||
|
||||
//===========================================================================
|
||||
void MemoryTextFile_t::PushLine( char *pLine )
|
||||
void MemoryTextFile_t::PushLine( const char *pLine )
|
||||
{
|
||||
char *pSrc = pLine;
|
||||
const char *pSrc = pLine;
|
||||
while (pSrc && *pSrc)
|
||||
{
|
||||
if (*pSrc == CHAR_CR)
|
||||
|
@ -141,4 +142,10 @@ void MemoryTextFile_t::PushLine( char *pLine )
|
|||
m_bDirty = true;
|
||||
}
|
||||
|
||||
|
||||
void MemoryTextFile_t::PushLineFormat( const char *pFormat, ... )
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, pFormat);
|
||||
PushLine(StrFormatV(pFormat, va).c_str());
|
||||
va_end(va);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "StrFormat.h"
|
||||
|
||||
// Memory Text File _________________________________________________________
|
||||
|
||||
class MemoryTextFile_t
|
||||
|
@ -43,6 +45,7 @@ inline char *GetLine( const int iLine ) const
|
|||
|
||||
void GetLine( const int iLine, char *pLine, const int n );
|
||||
|
||||
void PushLine( char *pLine );
|
||||
void PushLine( const char *pLine );
|
||||
void PushLineFormat( const char *pFormat, ... ) ATTRIBUTE_FORMAT_PRINTF(2, 3); // 1 is "this"
|
||||
};
|
||||
|
||||
|
|
494
source/Disk.cpp
494
source/Disk.cpp
|
@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#include "Interface.h"
|
||||
#include "Core.h"
|
||||
#include "CardManager.h"
|
||||
#include "CPU.h"
|
||||
#include "DiskImage.h"
|
||||
#include "Log.h"
|
||||
|
@ -58,7 +59,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
const BYTE Disk2InterfaceCard::m_T00S00Pattern[] = {0xD5,0xAA,0x96,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xDE};
|
||||
|
||||
Disk2InterfaceCard::Disk2InterfaceCard(UINT slot) :
|
||||
Card(CT_Disk2, slot)
|
||||
Card(CT_Disk2, slot),
|
||||
m_syncEvent(slot, 0, SyncEventCallback) // use slot# as "unique" id for Disk2InterfaceCards
|
||||
{
|
||||
if (m_slot != 5 && m_slot != 6) // fixme
|
||||
ThrowErrorInvalidSlot();
|
||||
|
@ -71,13 +73,13 @@ Disk2InterfaceCard::Disk2InterfaceCard(UINT slot) :
|
|||
m_diskLastReadLatchCycle = 0;
|
||||
m_enhanceDisk = true;
|
||||
m_is13SectorFirmware = false;
|
||||
m_force13SectorFirmware = false;
|
||||
m_deferredStepperEvent = false;
|
||||
m_deferredStepperAddress = 0;
|
||||
m_deferredStepperCumulativeCycles = 0;
|
||||
|
||||
ResetLogicStateSequencer();
|
||||
|
||||
// if created by user in Config->Disk, then MemInitializeIO() won't be called
|
||||
if (GetCxRomPeripheral())
|
||||
InitializeIO(GetCxRomPeripheral()); // During regular start-up, Initialize() will be called later by MemInitializeIO()
|
||||
|
||||
// Debug:
|
||||
#if LOG_DISK_NIBBLES_USE_RUNTIME_VAR
|
||||
m_bLogDisk_NibblesRW = false;
|
||||
|
@ -93,8 +95,8 @@ Disk2InterfaceCard::~Disk2InterfaceCard(void)
|
|||
EjectDiskInternal(DRIVE_1);
|
||||
EjectDiskInternal(DRIVE_2);
|
||||
|
||||
// if destroyed by user in Config->Disk, then ensure that old object's reference is removed
|
||||
UnregisterIoHandler(m_slot);
|
||||
if (m_syncEvent.m_active)
|
||||
g_SynchronousEventMgr.Remove(m_syncEvent.m_id);
|
||||
}
|
||||
|
||||
bool Disk2InterfaceCard::GetEnhanceDisk(void) { return m_enhanceDisk; }
|
||||
|
@ -103,27 +105,31 @@ void Disk2InterfaceCard::SetEnhanceDisk(bool bEnhanceDisk) { m_enhanceDisk = bEn
|
|||
int Disk2InterfaceCard::GetCurrentDrive(void) { return m_currDrive; }
|
||||
int Disk2InterfaceCard::GetCurrentTrack(void) { return ImagePhaseToTrack(m_floppyDrive[m_currDrive].m_disk.m_imagehandle, m_floppyDrive[m_currDrive].m_phasePrecise, false); }
|
||||
float Disk2InterfaceCard::GetCurrentPhase(void) { return m_floppyDrive[m_currDrive].m_phasePrecise; }
|
||||
int Disk2InterfaceCard::GetCurrentOffset(void) { return m_floppyDrive[m_currDrive].m_disk.m_byte; }
|
||||
BYTE Disk2InterfaceCard::GetCurrentLSSBitMask(void) { return m_floppyDrive[m_currDrive].m_disk.m_bitMask; }
|
||||
UINT Disk2InterfaceCard::GetCurrentBitOffset(void) { return m_floppyDrive[m_currDrive].m_disk.m_bitOffset; }
|
||||
double Disk2InterfaceCard::GetCurrentExtraCycles(void) { return m_floppyDrive[m_currDrive].m_disk.m_extraCycles; }
|
||||
float Disk2InterfaceCard::GetPhase(const int drive) { return m_floppyDrive[drive].m_phasePrecise; }
|
||||
int Disk2InterfaceCard::GetTrack(const int drive) { return ImagePhaseToTrack(m_floppyDrive[drive].m_disk.m_imagehandle, m_floppyDrive[drive].m_phasePrecise, false); }
|
||||
|
||||
std::string Disk2InterfaceCard::FormatPhaseString(float phase)
|
||||
std::string Disk2InterfaceCard::FormatIntFracString(float phase, bool hex)
|
||||
{
|
||||
const UINT phaseInt = (UINT)phase;
|
||||
const UINT phaseFrac = (UINT)((phase - (float)phaseInt) * 100 + 0.5);
|
||||
|
||||
return StrFormat("%02X.%2d", phaseInt, phaseFrac); // "$NN.nn"
|
||||
if (hex)
|
||||
return StrFormat("%02X.%02d", phaseInt, phaseFrac); // (hex)"NN.nn"
|
||||
else
|
||||
return StrFormat("%02d.%02d", phaseInt, phaseFrac); // (dec)"NN.nn"
|
||||
|
||||
}
|
||||
|
||||
std::string Disk2InterfaceCard::GetCurrentTrackString(void)
|
||||
{
|
||||
return FormatPhaseString(m_floppyDrive[m_currDrive].m_phasePrecise / 2);
|
||||
return FormatIntFracString(m_floppyDrive[m_currDrive].m_phasePrecise / 2, true);
|
||||
}
|
||||
|
||||
std::string Disk2InterfaceCard::GetCurrentPhaseString(void)
|
||||
{
|
||||
return FormatPhaseString(m_floppyDrive[m_currDrive].m_phasePrecise);
|
||||
return FormatIntFracString(m_floppyDrive[m_currDrive].m_phasePrecise, true);
|
||||
}
|
||||
|
||||
LPCTSTR Disk2InterfaceCard::GetCurrentState(void)
|
||||
|
@ -300,8 +306,15 @@ void Disk2InterfaceCard::ReadTrack(const int drive, ULONG uExecutedCycles)
|
|||
UpdateBitStreamPosition(*pFloppy, bitCellDelta);
|
||||
}
|
||||
|
||||
const UINT32 currentPosition = pFloppy->m_byte;
|
||||
const UINT32 currentTrackLength = pFloppy->m_nibbles;
|
||||
if (ImageIsWOZ(pFloppy->m_imagehandle) && (pFloppy->m_bitCount == 0))
|
||||
{
|
||||
// WOZ: m_bitCount only ever 0 on initial power on
|
||||
pFloppy->m_bitOffset = 0;
|
||||
pFloppy->m_bitCount = 8;
|
||||
}
|
||||
|
||||
const UINT32 currentBitPosition = pFloppy->m_bitOffset;
|
||||
const UINT32 currentBitTrackLength = pFloppy->m_bitCount;
|
||||
|
||||
ImageReadTrack(
|
||||
pFloppy->m_imagehandle,
|
||||
|
@ -311,12 +324,18 @@ void Disk2InterfaceCard::ReadTrack(const int drive, ULONG uExecutedCycles)
|
|||
&pFloppy->m_bitCount,
|
||||
m_enhanceDisk);
|
||||
|
||||
if (!ImageIsWOZ(pFloppy->m_imagehandle) || (currentTrackLength == 0))
|
||||
if (!ImageIsWOZ(pFloppy->m_imagehandle))
|
||||
{
|
||||
pFloppy->m_byte = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NB. This function is only called for a new track when there's a latch read, ie. only for *even* DEVICE SELECT I/O accesses.
|
||||
// . So when seeking across tracks (ie. sequencing through the magnet phases), then not all (quarter) tracks will need reading.
|
||||
// . eg. for 'Balance of Power'(GH#1022), for seek T00->T35: this only reads: 00.00, 00.25, 00.75, 01.25, 01.75, ... 34.25, 34.75, 35.00 (skipping the NN.00, NN.50 tracks).
|
||||
// . And so the bitOffset "round-up" below isn't called for every track.
|
||||
// TODO: consider forcing this function be be called for every track (and appropriately adjust the "round-up" amount - ie. halve it)
|
||||
|
||||
_ASSERT(pFloppy->m_nibbles && pFloppy->m_bitCount);
|
||||
if (pFloppy->m_nibbles == 0 || pFloppy->m_bitCount == 0)
|
||||
{
|
||||
|
@ -324,18 +343,28 @@ void Disk2InterfaceCard::ReadTrack(const int drive, ULONG uExecutedCycles)
|
|||
pFloppy->m_bitCount = 8;
|
||||
}
|
||||
|
||||
pFloppy->m_byte = (currentPosition * pFloppy->m_nibbles) / currentTrackLength; // Ref: WOZ-1.01
|
||||
pFloppy->m_bitOffset = (currentBitPosition * pFloppy->m_bitCount) / currentBitTrackLength; // Ref: WOZ-1.01
|
||||
pFloppy->m_bitOffset += 7; // Round-up for sensitive cross-track sync check (GH#1022)
|
||||
|
||||
if (pFloppy->m_byte == (pFloppy->m_nibbles-1)) // Last nibble may not be complete, so advance by 1 nibble
|
||||
pFloppy->m_byte = 0;
|
||||
if (pFloppy->m_bitOffset >= pFloppy->m_bitCount)
|
||||
pFloppy->m_bitOffset = 0;
|
||||
#if LOG_DISK_WOZ_READTRACK
|
||||
LOG_DISK("T%05.2f: %04X->%04X, Len=%04X\n", pDrive->m_phasePrecise / 2, currentBitPosition, pFloppy->m_bitOffset, pFloppy->m_bitCount);
|
||||
#endif
|
||||
|
||||
pFloppy->m_byte = pFloppy->m_bitOffset / 8;
|
||||
pFloppy->m_bitMask = 1 << (7 - (pFloppy->m_bitOffset % 8));
|
||||
|
||||
pFloppy->m_bitOffset = pFloppy->m_byte*8;
|
||||
pFloppy->m_bitMask = 1 << 7;
|
||||
pFloppy->m_extraCycles = 0.0;
|
||||
pDrive->m_headWindow = 0;
|
||||
|
||||
FindTrackSeamWOZ(*pFloppy, pDrive->m_phasePrecise/2);
|
||||
}
|
||||
|
||||
pFloppy->m_trackimagedata = (pFloppy->m_nibbles != 0);
|
||||
|
||||
pFloppy->m_initialBitOffset = pFloppy->m_bitOffset;
|
||||
pFloppy->m_revs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,7 +491,6 @@ void __stdcall Disk2InterfaceCard::ControlMotor(WORD, WORD address, BYTE, BYTE,
|
|||
void __stdcall Disk2InterfaceCard::ControlStepper(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
||||
{
|
||||
FloppyDrive* pDrive = &m_floppyDrive[m_currDrive];
|
||||
FloppyDisk* pFloppy = &pDrive->m_disk;
|
||||
|
||||
if (!m_floppyMotorOn) // GH#525
|
||||
{
|
||||
|
@ -491,16 +519,80 @@ void __stdcall Disk2InterfaceCard::ControlStepper(WORD, WORD address, BYTE, BYTE
|
|||
m_magnetStates &= ~phase_bit; // phase off
|
||||
}
|
||||
|
||||
#if LOG_DISK_PHASES
|
||||
const ULONG cycleDelta = (ULONG)(g_nCumulativeCycles - pDrive->m_lastStepperCycle);
|
||||
#endif
|
||||
pDrive->m_lastStepperCycle = g_nCumulativeCycles;
|
||||
if (!GetCardMgr().GetDisk2CardMgr().IsStepperDeferred())
|
||||
{
|
||||
m_deferredStepperAddress = address;
|
||||
m_deferredStepperCumulativeCycles = g_nCumulativeCycles;
|
||||
ControlStepperDeferred();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_syncEvent.m_active)
|
||||
{
|
||||
// Check for adjacent magnets being turned off/on in a very short interval (10 cycles is purely based on A2osX). (GH#1110)
|
||||
g_SynchronousEventMgr.Remove(m_syncEvent.m_id);
|
||||
m_deferredStepperEvent = false;
|
||||
|
||||
int addrDelta = (m_deferredStepperAddress & 7) - (address & 7);
|
||||
if (addrDelta < 0) addrDelta = -addrDelta;
|
||||
if (addrDelta == 2 || addrDelta == 6) // adjacent magnets: both turned off or both turned on
|
||||
{
|
||||
if ((address & 1) == 0) // adjacent magnets off
|
||||
{
|
||||
// 2 adjacent magnets off in quick succession don't move the cog (GH#1110)
|
||||
// . also DOS3.2, Pascal and ProDOS rapidly turning off all 4 magnets.
|
||||
ControlStepperLogging(m_deferredStepperAddress, m_deferredStepperCumulativeCycles);
|
||||
ControlStepperLogging(address, g_nCumulativeCycles);
|
||||
return;
|
||||
}
|
||||
else // adjacent magnets turned on
|
||||
{
|
||||
// take no action - can't find any titles that ever do this!
|
||||
const std::string msg = "Disk: ControlStepper() - adjacent magnets turned on\n";
|
||||
LogOutput("%s", msg.c_str());
|
||||
LogFileOutput("%s", msg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// complete the deferred stepper event
|
||||
// eg. Glutton, EDD III - both just combinations of turning off all 4 magnets
|
||||
ControlStepperDeferred();
|
||||
}
|
||||
|
||||
// defer the effect of changing the phase
|
||||
m_deferredStepperAddress = address;
|
||||
m_deferredStepperCumulativeCycles = g_nCumulativeCycles;
|
||||
InsertSyncEvent();
|
||||
m_deferredStepperEvent = true;
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::InsertSyncEvent(void)
|
||||
{
|
||||
m_syncEvent.m_cyclesRemaining = 10; // NB. same cycle delay for magnet off and on - but perhaps they take different times?
|
||||
g_SynchronousEventMgr.Insert(&m_syncEvent);
|
||||
}
|
||||
|
||||
int Disk2InterfaceCard::SyncEventCallback(int id, int cycles, ULONG uExecutedCycles)
|
||||
{
|
||||
Disk2InterfaceCard& disk2Card = dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(id));
|
||||
disk2Card.ControlStepperDeferred();
|
||||
return 0; // Don't repeat event
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::ControlStepperDeferred(void)
|
||||
{
|
||||
m_deferredStepperEvent = false;
|
||||
const WORD address = m_deferredStepperAddress;
|
||||
|
||||
FloppyDrive* pDrive = &m_floppyDrive[m_currDrive];
|
||||
FloppyDisk* pFloppy = &pDrive->m_disk;
|
||||
|
||||
// check for any stepping effect from a magnet
|
||||
// - move only when the magnet opposite the cog is off
|
||||
// - move in the direction of an adjacent magnet if one is on
|
||||
// - do not move if both adjacent magnets are on (ie. quarter track)
|
||||
// momentum and timing are not accounted for ... maybe one day!
|
||||
// - timing is accounted for in the case when "two phases [are] turned off in rapid sequence" (UTAIIe page 9-13) (GH#1110)
|
||||
// momentum is not accounted for ... maybe one day!
|
||||
int direction = 0;
|
||||
if (m_magnetStates & (1 << ((pDrive->m_phase + 1) & 3)))
|
||||
direction += 1;
|
||||
|
@ -536,9 +628,21 @@ void __stdcall Disk2InterfaceCard::ControlStepper(WORD, WORD address, BYTE, BYTE
|
|||
GetFrame().FrameDrawDiskStatus(); // Show track status (GH#201)
|
||||
}
|
||||
|
||||
ControlStepperLogging(address, m_deferredStepperCumulativeCycles);
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::ControlStepperLogging(WORD address, unsigned __int64 cumulativeCycles)
|
||||
{
|
||||
FloppyDrive* pDrive = &m_floppyDrive[m_currDrive];
|
||||
|
||||
#if LOG_DISK_PHASES
|
||||
const ULONG cycleDelta = (ULONG)(cumulativeCycles - pDrive->m_lastStepperCycle);
|
||||
#endif
|
||||
pDrive->m_lastStepperCycle = cumulativeCycles; // NB. Persisted to save-state
|
||||
|
||||
#if LOG_DISK_PHASES
|
||||
LOG_DISK("%08X: track $%s magnet-states %d%d%d%d phase %d %s address $%4X last-stepper %.3fms\r\n",
|
||||
(UINT32)g_nCumulativeCycles,
|
||||
(UINT32)cumulativeCycles,
|
||||
GetCurrentTrackString().c_str(),
|
||||
(m_magnetStates >> 3) & 1,
|
||||
(m_magnetStates >> 2) & 1,
|
||||
|
@ -547,7 +651,7 @@ void __stdcall Disk2InterfaceCard::ControlStepper(WORD, WORD address, BYTE, BYTE
|
|||
(address >> 1) & 3, // phase
|
||||
(address & 1) ? "on " : "off",
|
||||
address,
|
||||
((float)cycleDelta)/(CLK_6502_NTSC/1000.0));
|
||||
((float)cycleDelta) / (CLK_6502_NTSC / 1000.0));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1035,7 +1139,6 @@ void Disk2InterfaceCard::ResetLogicStateSequencer(void)
|
|||
{
|
||||
m_shiftReg = 0;
|
||||
m_latchDelay = 0;
|
||||
m_resetSequencer = true;
|
||||
m_writeStarted = false;
|
||||
m_dbgLatchDelayedCnt = 0;
|
||||
|
||||
|
@ -1087,8 +1190,6 @@ void Disk2InterfaceCard::UpdateBitStreamPosition(FloppyDisk& floppy, const ULONG
|
|||
floppy.m_bitOffset %= floppy.m_bitCount;
|
||||
|
||||
UpdateBitStreamOffsets(floppy);
|
||||
|
||||
m_resetSequencer = false;
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::UpdateBitStreamOffsets(FloppyDisk& floppy)
|
||||
|
@ -1114,6 +1215,9 @@ __forceinline void Disk2InterfaceCard::IncBitStream(FloppyDisk& floppy)
|
|||
floppy.m_bitOffset = 0;
|
||||
floppy.m_byte = 0;
|
||||
}
|
||||
|
||||
if (floppy.m_bitOffset == floppy.m_initialBitOffset)
|
||||
floppy.m_revs++;
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::PreJitterCheck(int phase, BYTE latch)
|
||||
|
@ -1158,6 +1262,29 @@ void Disk2InterfaceCard::AddJitter(int phase, FloppyDisk& floppy)
|
|||
m_foundT00S00Pattern = false;
|
||||
}
|
||||
|
||||
// GH#1125: For T$21 (track 33.0) or above (and sufficiently long sync FF/10 run-length), then randomly skip 1 bit-cell at the start of the FF/2 track seam.
|
||||
// Example of high sync FF/10 run-lengths for tracks 33.0+:
|
||||
// . Accolade Comics:114, Silent Service:117, Wings of Fury:140, Wizardry I:127, Wizardry III:283
|
||||
// NB. Restrict to higher FF/10 run-lengths to limit the titles affected by this jitter.
|
||||
void Disk2InterfaceCard::AddTrackSeamJitter(float phasePrecise, FloppyDisk& floppy)
|
||||
{
|
||||
if (phasePrecise >= (33.0 * 2) && floppy.m_longestSyncFFRunLength > 110)
|
||||
{
|
||||
if (floppy.m_bitOffset == floppy.m_longestSyncFFBitOffsetStart)
|
||||
{
|
||||
if (rand() < RAND_THRESHOLD(5, 10))
|
||||
{
|
||||
LogOutput("Disk: T%05.2f jitter - slip 1 bitcell (revs=%d) (PC=%04X)\n", phasePrecise / 2, floppy.m_revs, regs.pc);
|
||||
IncBitStream(floppy);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogOutput("Disk: T%05.2f jitter - *** SKIP *** (revs=%d) (PC=%04X)\n", phasePrecise / 2, floppy.m_revs, regs.pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __stdcall Disk2InterfaceCard::DataLatchReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, ULONG uExecutedCycles)
|
||||
{
|
||||
_ASSERT(m_seqFunc.function != dataShiftWrite);
|
||||
|
@ -1166,7 +1293,11 @@ void __stdcall Disk2InterfaceCard::DataLatchReadWriteWOZ(WORD pc, WORD addr, BYT
|
|||
FloppyDisk& floppy = drive.m_disk;
|
||||
|
||||
if (!floppy.m_trackimagedata && floppy.m_imagehandle)
|
||||
{
|
||||
ReadTrack(m_currDrive, uExecutedCycles);
|
||||
// NB. ReadTrack() has called GetBitCellDelta(), so the subsequent call to GetBitCellDelta() below just returns bitCellDelta==0
|
||||
// So could just return at this point.
|
||||
}
|
||||
|
||||
if (!floppy.m_trackimagedata)
|
||||
{
|
||||
|
@ -1260,13 +1391,7 @@ void Disk2InterfaceCard::DataLatchReadWOZ(WORD pc, WORD addr, UINT bitCellRemain
|
|||
|
||||
IncBitStream(floppy);
|
||||
|
||||
if (m_resetSequencer)
|
||||
{
|
||||
m_resetSequencer = false; // LSS takes some cycles to reset (ref?)
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
AddTrackSeamJitter(drive.m_phasePrecise, floppy);
|
||||
|
||||
m_shiftReg <<= 1;
|
||||
m_shiftReg |= outputBit;
|
||||
|
@ -1354,6 +1479,8 @@ void Disk2InterfaceCard::DataLoadWriteWOZ(WORD pc, WORD addr, UINT bitCellRemain
|
|||
LOG_DISK("load shiftReg with %02X (was: %02X)\n", m_floppyLatch, m_shiftReg);
|
||||
#endif
|
||||
m_shiftReg = m_floppyLatch;
|
||||
|
||||
floppy.m_longestSyncFFBitOffsetStart = -1; // invalidate the track seam location after a write
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::DataShiftWriteWOZ(WORD pc, WORD addr, ULONG uExecutedCycles)
|
||||
|
@ -1372,6 +1499,12 @@ void Disk2InterfaceCard::DataShiftWriteWOZ(WORD pc, WORD addr, ULONG uExecutedCy
|
|||
return;
|
||||
}
|
||||
|
||||
if (!drive.m_spinning)
|
||||
return;
|
||||
|
||||
if (!floppy.m_trackimagedata) // GH#1126
|
||||
return;
|
||||
|
||||
#if LOG_DISK_WOZ_SHIFTWRITE
|
||||
LOG_DISK("T$%02X, bitOffset=%04X: %02X (%d bits)\n", drive.m_phase/2, floppy.m_bitOffset, m_shiftReg, bitCellRemainder);
|
||||
#endif
|
||||
|
@ -1394,6 +1527,107 @@ void Disk2InterfaceCard::DataShiftWriteWOZ(WORD pc, WORD addr, ULONG uExecutedCy
|
|||
|
||||
//===========================================================================
|
||||
|
||||
// For now all that's needed is this basic case:
|
||||
// . find [start,end] of longest run of FF/10 sync nibbles
|
||||
void Disk2InterfaceCard::FindTrackSeamWOZ(FloppyDisk& floppy, float track)
|
||||
{
|
||||
const UINT oldBitOffset = floppy.m_bitOffset; // Save current state
|
||||
|
||||
BYTE shiftReg = 0;
|
||||
UINT zeroCount = 0;
|
||||
|
||||
int startBitOffset = -1; // NB. change this to start of first FF/10
|
||||
floppy.m_bitOffset = 0;
|
||||
UpdateBitStreamOffsets(floppy);
|
||||
|
||||
int nibbleStartBitOffset = -1;
|
||||
int syncFFStartBitOffset = -1;
|
||||
int syncFFRunLength = 0;
|
||||
int longestSyncFFStartBitOffset = -1;
|
||||
int longestSyncFFRunLength = 0;
|
||||
|
||||
floppy.m_longestSyncFFBitOffsetStart = -1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
BYTE n = floppy.m_trackimage[floppy.m_byte];
|
||||
BYTE outputBit = (n & floppy.m_bitMask) ? 1 : 0;
|
||||
|
||||
IncBitStream(floppy);
|
||||
|
||||
if ((startBitOffset < 0 && floppy.m_bitOffset == 0) || (startBitOffset == floppy.m_bitOffset)) // done complete track?
|
||||
break;
|
||||
|
||||
if (shiftReg & 0x80)
|
||||
{
|
||||
if (outputBit == 0) // zero, so LSS holds nibble in latch
|
||||
{
|
||||
zeroCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// else: start of next nibble
|
||||
|
||||
if (shiftReg == 0xff && zeroCount == 2)
|
||||
{
|
||||
if (syncFFStartBitOffset < 0)
|
||||
syncFFStartBitOffset = nibbleStartBitOffset;
|
||||
syncFFRunLength++;
|
||||
}
|
||||
|
||||
if ((shiftReg != 0xff || zeroCount != 2) && syncFFStartBitOffset >= 0)
|
||||
{
|
||||
// Longest FF/2 run could straddle end/start of track's bit buffer
|
||||
if (startBitOffset < 0)
|
||||
startBitOffset = nibbleStartBitOffset;
|
||||
|
||||
if (longestSyncFFRunLength < syncFFRunLength)
|
||||
{
|
||||
longestSyncFFStartBitOffset = syncFFStartBitOffset;
|
||||
longestSyncFFRunLength = syncFFRunLength;
|
||||
}
|
||||
syncFFStartBitOffset = -1;
|
||||
syncFFRunLength = 0;
|
||||
}
|
||||
|
||||
shiftReg = 0;
|
||||
zeroCount = 0;
|
||||
}
|
||||
|
||||
shiftReg <<= 1;
|
||||
shiftReg |= outputBit;
|
||||
|
||||
if (shiftReg == 0x01)
|
||||
{
|
||||
nibbleStartBitOffset = floppy.m_bitOffset - 1;
|
||||
if (nibbleStartBitOffset < 0) nibbleStartBitOffset += floppy.m_bitCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (longestSyncFFRunLength)
|
||||
{
|
||||
const int longestSyncFFBitOffsetEnd = (longestSyncFFStartBitOffset + longestSyncFFRunLength * 10 - 1) % floppy.m_bitCount;
|
||||
#if LOG_DISK_WOZ_TRACK_SEAM
|
||||
LOG_DISK("Track seam: T%05.2f: FF/10 (run=%d), start=%04X, end=%04X\n", track, longestSyncFFRunLength, longestSyncFFStartBitOffset, longestSyncFFBitOffsetEnd);
|
||||
#endif
|
||||
floppy.m_longestSyncFFBitOffsetStart = longestSyncFFStartBitOffset;
|
||||
floppy.m_longestSyncFFRunLength = longestSyncFFRunLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOG_DISK_WOZ_TRACK_SEAM
|
||||
LOG_DISK("Track seam: T%05.2f: FF/10 (none)\n", track);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Restore state
|
||||
|
||||
floppy.m_bitOffset = oldBitOffset;
|
||||
UpdateBitStreamOffsets(floppy);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Dump nibbles from current position bitstream wraps to same position
|
||||
// NB. Need to define LOG_DISK_NIBBLES_READ so that GetReadD5AAxxDetectedString() works.
|
||||
|
@ -1405,21 +1639,22 @@ void Disk2InterfaceCard::DumpTrackWOZ(FloppyDisk floppy) // pass a copy of m_flo
|
|||
UINT zeroCount = 0;
|
||||
UINT nibbleCount = 0;
|
||||
|
||||
const UINT startBitOffset = 0; // NB. may need to tweak this offset, since the bistream is a circular buffer
|
||||
const UINT startBitOffset = 0; // NB. may need to tweak this offset, since the bitstream is a circular buffer
|
||||
floppy.m_bitOffset = startBitOffset;
|
||||
UpdateBitStreamOffsets(floppy);
|
||||
|
||||
floppy.m_byte = floppy.m_bitOffset / 8;
|
||||
const UINT remainder = 7 - (floppy.m_bitOffset & 7);
|
||||
floppy.m_bitMask = 1 << remainder;
|
||||
int nibbleStartBitOffset = -1;
|
||||
|
||||
bool newLine = true;
|
||||
bool doneLastBit = false;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (newLine)
|
||||
if (newLine && nibbleStartBitOffset >= 0)
|
||||
{
|
||||
newLine = false;
|
||||
LogOutput("%04X:", floppy.m_bitOffset & 0xffff);
|
||||
LogOutput("%04X:", nibbleStartBitOffset);
|
||||
nibbleStartBitOffset = -1;
|
||||
}
|
||||
|
||||
BYTE n = floppy.m_trackimage[floppy.m_byte];
|
||||
|
@ -1428,53 +1663,67 @@ void Disk2InterfaceCard::DumpTrackWOZ(FloppyDisk floppy) // pass a copy of m_flo
|
|||
IncBitStream(floppy);
|
||||
|
||||
if (startBitOffset == floppy.m_bitOffset) // done complete track?
|
||||
doneLastBit = true;
|
||||
else if (doneLastBit)
|
||||
break;
|
||||
|
||||
if (shiftReg == 0 && outputBit == 0)
|
||||
if (shiftReg & 0x80)
|
||||
{
|
||||
zeroCount++;
|
||||
continue;
|
||||
if (outputBit == 0) // zero, so LSS holds nibble in latch
|
||||
{
|
||||
zeroCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// else: start of next nibble
|
||||
|
||||
nibbleCount++;
|
||||
|
||||
char syncBits = zeroCount <= 9 ? '0' + zeroCount : '+';
|
||||
if (zeroCount == 0) LogOutput("%02X ", shiftReg);
|
||||
else LogOutput("%02X(%c)", shiftReg, syncBits);
|
||||
|
||||
formatTrack.DecodeLatchNibbleRead(shiftReg);
|
||||
|
||||
if ((nibbleCount % 32) == 0)
|
||||
{
|
||||
std::string strReadDetected = formatTrack.GetReadD5AAxxDetectedString();
|
||||
if (!strReadDetected.empty())
|
||||
{
|
||||
OutputDebugString("\t; ");
|
||||
OutputDebugString(strReadDetected.c_str());
|
||||
}
|
||||
OutputDebugString("\n");
|
||||
newLine = true;
|
||||
}
|
||||
|
||||
shiftReg = 0;
|
||||
zeroCount = 0;
|
||||
}
|
||||
|
||||
shiftReg <<= 1;
|
||||
shiftReg |= outputBit;
|
||||
|
||||
if ((shiftReg & 0x80) == 0)
|
||||
continue;
|
||||
|
||||
nibbleCount++;
|
||||
|
||||
char syncBits = zeroCount <= 9 ? '0'+zeroCount : '+';
|
||||
if (zeroCount == 0) LogOutput(" %02X", shiftReg);
|
||||
else LogOutput("(%c)%02X", syncBits, shiftReg);
|
||||
|
||||
formatTrack.DecodeLatchNibbleRead(shiftReg);
|
||||
|
||||
if ((nibbleCount % 32) == 0)
|
||||
if (shiftReg == 0x01)
|
||||
{
|
||||
std::string strReadDetected = formatTrack.GetReadD5AAxxDetectedString();
|
||||
if (!strReadDetected.empty())
|
||||
{
|
||||
OutputDebugString("\t; ");
|
||||
OutputDebugString(strReadDetected.c_str());
|
||||
}
|
||||
OutputDebugString("\n");
|
||||
newLine = true;
|
||||
nibbleStartBitOffset = floppy.m_bitOffset - 1;
|
||||
if (nibbleStartBitOffset < 0) nibbleStartBitOffset += floppy.m_bitCount;
|
||||
}
|
||||
|
||||
shiftReg = 0;
|
||||
zeroCount = 0;
|
||||
}
|
||||
|
||||
// Output any remaining zeroCount
|
||||
if (zeroCount)
|
||||
{
|
||||
char syncBits = zeroCount <= 9 ? '0'+zeroCount : '+';
|
||||
LogOutput("(%c)", syncBits);
|
||||
}
|
||||
|
||||
// Output any partial nibble
|
||||
if (shiftReg)
|
||||
if (shiftReg & 0x80)
|
||||
{
|
||||
LogOutput("%02X", shiftReg);
|
||||
|
||||
// Output any remaining zeroCount
|
||||
if (zeroCount)
|
||||
{
|
||||
char syncBits = zeroCount <= 9 ? '0' + zeroCount : '+';
|
||||
LogOutput("(%c)", syncBits);
|
||||
}
|
||||
}
|
||||
else if (shiftReg)
|
||||
{
|
||||
LogOutput("%02X/Partial Nibble", shiftReg);
|
||||
}
|
||||
|
@ -1587,10 +1836,6 @@ bool Disk2InterfaceCard::UserSelectNewDiskImage(const int drive, LPCSTR pszFilen
|
|||
|
||||
void __stdcall Disk2InterfaceCard::LoadWriteProtect(WORD, WORD, BYTE write, BYTE value, ULONG uExecutedCycles)
|
||||
{
|
||||
// NB. Only reads in LOAD mode can issue the SR (shift write-protect) operation - UTAIIe page 9-20, fig 9.11
|
||||
// But STA $C08D,X (no PX) does a read from $C08D+X, followed by the write to $C08D+X
|
||||
// So just want to ignore: STA $C0ED or eg. STA $BFFF,X (PX, X=$EE)
|
||||
|
||||
// Don't change latch if drive off after 1 second drive-off delay (UTAIIe page 9-13)
|
||||
// "DRIVES OFF forces the data register to hold its present state." (UTAIIe page 9-12)
|
||||
// Note: Gemstone Warrior sets load mode with the drive off.
|
||||
|
@ -1598,17 +1843,19 @@ void __stdcall Disk2InterfaceCard::LoadWriteProtect(WORD, WORD, BYTE write, BYTE
|
|||
return;
|
||||
|
||||
// Notes:
|
||||
// . Only READ-LOAD mode ($C08E,X & $C08D,X) can issue the SR (shift write-protect) operation - UTAIIe page 9-20, fig 9.11
|
||||
// . Phase 1 on also forces write protect in the Disk II drive (UTAIIe page 9-7) but we don't implement that.
|
||||
// . write mode doesn't prevent reading write protect (GH#537):
|
||||
// "If for some reason the above write protect check were entered with the READ/WRITE switch in WRITE,
|
||||
// the write protect switch would still be read correctly" (UTAIIe page 9-21)
|
||||
// . Sequencer "SR" (Shift Right) command only loads QA (bit7) of data register (UTAIIe page 9-21)
|
||||
// . Sequencer "SR" (Shift Right) command shifts the data register right and loads QA (bit7) with write protect (UTAIIe page 9-21)
|
||||
// . A read or write will shift 'write protect' in QA.
|
||||
// . The LSS saturates the data register before the CPU can read an intermediate value: so set to 0xFF or 0x00 (GH#1078)
|
||||
FloppyDisk& floppy = m_floppyDrive[m_currDrive].m_disk;
|
||||
if (floppy.m_bWriteProtected)
|
||||
m_floppyLatch |= 0x80;
|
||||
m_floppyLatch = 0xFF;
|
||||
else
|
||||
m_floppyLatch &= 0x7F;
|
||||
m_floppyLatch = 0x00;
|
||||
|
||||
if (m_writeStarted) // Prevent ResetLogicStateSequencer() from resetting m_writeStarted
|
||||
return;
|
||||
|
@ -1622,9 +1869,7 @@ void __stdcall Disk2InterfaceCard::LoadWriteProtect(WORD, WORD, BYTE write, BYTE
|
|||
const UINT bitCellDelta = GetBitCellDelta(uExecutedCycles);
|
||||
UpdateBitStreamPosition(floppy, bitCellDelta); // Fix E7-copy protection
|
||||
|
||||
// UpdateBitStreamPosition() must be done before ResetLSS, as the former clears m_resetSequencer (and the latter sets it).
|
||||
// . Commando.woz is sensitive to this. EG. It can crash after pressing 'J' (1 failure in 20 reboot repeats)
|
||||
ResetLogicStateSequencer(); // reset sequencer (UTAIIe page 9-21)
|
||||
ResetLogicStateSequencer(); // "Set the sequencer to State 0" (UTAIIe page 9-21)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1765,7 +2010,10 @@ void Disk2InterfaceCard::InitFirmware(LPBYTE pCxRomPeripheral)
|
|||
|
||||
ImageInfo* pImage = m_floppyDrive[DRIVE_1].m_disk.m_imagehandle;
|
||||
|
||||
m_is13SectorFirmware = ImageIsBootSectorFormatSector13(pImage);
|
||||
if (m_force13SectorFirmware)
|
||||
m_is13SectorFirmware = true;
|
||||
else
|
||||
m_is13SectorFirmware = ImageIsBootSectorFormatSector13(pImage);
|
||||
|
||||
if (m_is13SectorFirmware)
|
||||
memcpy(pCxRomPeripheral + m_slot*APPLE_SLOT_SIZE, m_13SectorFirmware, DISK2_FW_SIZE);
|
||||
|
@ -1795,21 +2043,35 @@ void Disk2InterfaceCard::InitializeIO(LPBYTE pCxRomPeripheral)
|
|||
|
||||
//===========================================================================
|
||||
|
||||
void Disk2InterfaceCard::SetSequencerFunction(WORD addr)
|
||||
void Disk2InterfaceCard::SetSequencerFunction(WORD addr, ULONG executedCycles)
|
||||
{
|
||||
if ((addr & 0xf) < 0xc)
|
||||
return;
|
||||
|
||||
const SEQFUNC oldSeqFunc = m_seqFunc.function;
|
||||
|
||||
switch ((addr & 3) ^ 2)
|
||||
{
|
||||
case 0: m_seqFunc.writeMode = 0; break; // $C08E,X (sequence addr A2 input)
|
||||
case 1: m_seqFunc.writeMode = 1; break; // $C08F,X (sequence addr A2 input)
|
||||
case 2: m_seqFunc.loadMode = 0; break; // $C08C,X (sequence addr A3 input)
|
||||
case 3: m_seqFunc.loadMode = 1; break; // $C08D,X (sequence addr A3 input)
|
||||
case 0: m_seqFunc.writeMode = 0; break; // $C08E,X (sequence addr A3 input)
|
||||
case 1: m_seqFunc.writeMode = 1; break; // $C08F,X (sequence addr A3 input)
|
||||
case 2: m_seqFunc.loadMode = 0; break; // $C08C,X (sequence addr A2 input)
|
||||
case 3: m_seqFunc.loadMode = 1; break; // $C08D,X (sequence addr A2 input)
|
||||
}
|
||||
|
||||
if (!m_seqFunc.writeMode)
|
||||
m_writeStarted = false;
|
||||
|
||||
if (oldSeqFunc == checkWriteProtAndInitWrite && m_seqFunc.function != checkWriteProtAndInitWrite)
|
||||
{
|
||||
// Use up remaining cycles before switching out of "checkWriteProtAndInitWrite" mode
|
||||
// Done when checking write-protect, but also for bit-slip (eg. E7) copy-protections
|
||||
FloppyDisk& floppy = m_floppyDrive[m_currDrive].m_disk;
|
||||
if (ImageIsWOZ(floppy.m_imagehandle))
|
||||
{
|
||||
const UINT bitCellDelta = GetBitCellDelta(executedCycles);
|
||||
UpdateBitStreamPosition(floppy, bitCellDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BYTE __stdcall Disk2InterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles)
|
||||
|
@ -1825,7 +2087,7 @@ BYTE __stdcall Disk2InterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE
|
|||
if (isWOZ && pCard->m_seqFunc.function == dataShiftWrite) // Occurs at end of sector write ($C0EE)
|
||||
pCard->DataShiftWriteWOZ(pc, addr, nExecutedCycles); // Finish any previous write
|
||||
|
||||
pCard->SetSequencerFunction(addr);
|
||||
pCard->SetSequencerFunction(addr, nExecutedCycles);
|
||||
|
||||
switch (addr & 0xF)
|
||||
{
|
||||
|
@ -1872,7 +2134,7 @@ BYTE __stdcall Disk2InterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE
|
|||
if (isWOZ && pCard->m_seqFunc.function == dataShiftWrite)
|
||||
pCard->DataShiftWriteWOZ(pc, addr, nExecutedCycles); // Finish any previous write
|
||||
|
||||
pCard->SetSequencerFunction(addr);
|
||||
pCard->SetSequencerFunction(addr, nExecutedCycles);
|
||||
|
||||
switch (addr & 0xF)
|
||||
{
|
||||
|
@ -1915,13 +2177,15 @@ BYTE __stdcall Disk2InterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE
|
|||
// Split up 'Unit' putting some state into a new 'Floppy'
|
||||
// 5: Added: Sequencer Function
|
||||
// 6: Added: Drive Connected & Motor On Cycle
|
||||
static const UINT kUNIT_VERSION = 6;
|
||||
// 7: Deprecated SS_YAML_KEY_LSS_RESET_SEQUENCER, SS_YAML_KEY_DISK_ACCESSED
|
||||
// 8: Added: deferred stepper: event, address & cycle
|
||||
static const UINT kUNIT_VERSION = 8;
|
||||
|
||||
#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_DISK_ACCESSED "Disk Accessed" // deprecated at v7
|
||||
#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"
|
||||
|
@ -1930,8 +2194,11 @@ static const UINT kUNIT_VERSION = 6;
|
|||
#define SS_YAML_KEY_LAST_READ_LATCH_CYCLE "Last Read Latch Cycle"
|
||||
#define SS_YAML_KEY_LSS_SHIFT_REG "LSS Shift Reg"
|
||||
#define SS_YAML_KEY_LSS_LATCH_DELAY "LSS Latch Delay"
|
||||
#define SS_YAML_KEY_LSS_RESET_SEQUENCER "LSS Reset Sequencer"
|
||||
#define SS_YAML_KEY_LSS_RESET_SEQUENCER "LSS Reset Sequencer" // deprecated at v7
|
||||
#define SS_YAML_KEY_LSS_SEQUENCER_FUNCTION "LSS Sequencer Function"
|
||||
#define SS_YAML_KEY_DEFERRED_STEPPER_EVENT "Deferred Stepper Event"
|
||||
#define SS_YAML_KEY_DEFERRED_STEPPER_ADDRESS "Deferred Stepper Address"
|
||||
#define SS_YAML_KEY_DEFERRED_STEPPER_CYCLE "Deferred Stepper Cycle"
|
||||
|
||||
#define SS_YAML_KEY_DISK2UNIT "Unit"
|
||||
#define SS_YAML_KEY_DRIVE_CONNECTED "Drive Connected"
|
||||
|
@ -2004,7 +2271,6 @@ void Disk2InterfaceCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
|||
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_CURRENT_DRIVE, m_currDrive);
|
||||
yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_PHASES, m_magnetStates);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_DISK_ACCESSED, false); // deprecated
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_ENHANCE_DISK, m_enhanceDisk);
|
||||
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_FLOPPY_LATCH, m_floppyLatch);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_FLOPPY_MOTOR_ON, m_floppyMotorOn == TRUE);
|
||||
|
@ -2012,8 +2278,10 @@ void Disk2InterfaceCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
|||
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_LAST_READ_LATCH_CYCLE, m_diskLastReadLatchCycle); // v3
|
||||
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_LSS_SHIFT_REG, m_shiftReg); // v4
|
||||
yamlSaveHelper.SaveInt(SS_YAML_KEY_LSS_LATCH_DELAY, m_latchDelay); // v4
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_LSS_RESET_SEQUENCER, m_resetSequencer); // v4
|
||||
yamlSaveHelper.SaveInt(SS_YAML_KEY_LSS_SEQUENCER_FUNCTION, m_seqFunc.function); // v5
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_DEFERRED_STEPPER_EVENT, m_deferredStepperEvent); // v8
|
||||
yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_DEFERRED_STEPPER_ADDRESS, m_deferredStepperAddress); // v8
|
||||
yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_DEFERRED_STEPPER_CYCLE, m_deferredStepperCumulativeCycles); // v8
|
||||
m_formatTrack.SaveSnapshot(yamlSaveHelper); // v2
|
||||
|
||||
SaveSnapshotDriveUnit(yamlSaveHelper, DRIVE_1);
|
||||
|
@ -2170,7 +2438,6 @@ bool Disk2InterfaceCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT versi
|
|||
|
||||
m_currDrive = yamlLoadHelper.LoadUint(SS_YAML_KEY_CURRENT_DRIVE);
|
||||
m_magnetStates = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASES);
|
||||
(void) yamlLoadHelper.LoadBool(SS_YAML_KEY_DISK_ACCESSED); // deprecated - but retrieve the value to avoid the "State: Unknown key (Disk Accessed)" warning
|
||||
m_enhanceDisk = yamlLoadHelper.LoadBool(SS_YAML_KEY_ENHANCE_DISK);
|
||||
m_floppyLatch = yamlLoadHelper.LoadUint(SS_YAML_KEY_FLOPPY_LATCH);
|
||||
m_floppyMotorOn = yamlLoadHelper.LoadBool(SS_YAML_KEY_FLOPPY_MOTOR_ON);
|
||||
|
@ -2190,7 +2457,11 @@ bool Disk2InterfaceCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT versi
|
|||
{
|
||||
m_shiftReg = yamlLoadHelper.LoadUint(SS_YAML_KEY_LSS_SHIFT_REG) & 0xff;
|
||||
m_latchDelay = yamlLoadHelper.LoadInt(SS_YAML_KEY_LSS_LATCH_DELAY);
|
||||
m_resetSequencer = yamlLoadHelper.LoadBool(SS_YAML_KEY_LSS_RESET_SEQUENCER);
|
||||
}
|
||||
|
||||
if (version >= 4 && version <= 6)
|
||||
{
|
||||
(void) yamlLoadHelper.LoadBool(SS_YAML_KEY_LSS_RESET_SEQUENCER); // deprecated
|
||||
}
|
||||
|
||||
if (version >= 5)
|
||||
|
@ -2203,6 +2474,18 @@ bool Disk2InterfaceCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT versi
|
|||
m_seqFunc.loadMode = 0; // Wasn't saved until v5
|
||||
}
|
||||
|
||||
if (version <= 6)
|
||||
{
|
||||
(void) yamlLoadHelper.LoadBool(SS_YAML_KEY_DISK_ACCESSED); // deprecated - but retrieve the value to avoid the "State: Unknown key (Disk Accessed)" warning
|
||||
}
|
||||
|
||||
if (version >= 8)
|
||||
{
|
||||
m_deferredStepperEvent = yamlLoadHelper.LoadBool(SS_YAML_KEY_DEFERRED_STEPPER_EVENT);
|
||||
m_deferredStepperAddress = yamlLoadHelper.LoadUint(SS_YAML_KEY_DEFERRED_STEPPER_ADDRESS);
|
||||
m_deferredStepperCumulativeCycles = yamlLoadHelper.LoadUint64(SS_YAML_KEY_DEFERRED_STEPPER_CYCLE);
|
||||
}
|
||||
|
||||
// Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1
|
||||
for (UINT i=0; i<NUM_DRIVES; i++)
|
||||
{
|
||||
|
@ -2215,5 +2498,8 @@ bool Disk2InterfaceCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT versi
|
|||
|
||||
GetFrame().FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES | DRAW_DISK_STATUS);
|
||||
|
||||
if (m_deferredStepperEvent)
|
||||
InsertSyncEvent();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "DiskLog.h"
|
||||
#include "DiskFormatTrack.h"
|
||||
#include "DiskImage.h"
|
||||
#include "SynchronousEventManager.h"
|
||||
|
||||
enum Drive_e
|
||||
{
|
||||
|
@ -67,6 +68,10 @@ public:
|
|||
m_trackimage = NULL;
|
||||
m_trackimagedata = false;
|
||||
m_trackimagedirty = false;
|
||||
m_longestSyncFFRunLength = 0;
|
||||
m_longestSyncFFBitOffsetStart = -1;
|
||||
m_initialBitOffset = 0;
|
||||
m_revs = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -84,6 +89,10 @@ public:
|
|||
LPBYTE m_trackimage;
|
||||
bool m_trackimagedata;
|
||||
bool m_trackimagedirty;
|
||||
UINT m_longestSyncFFRunLength;
|
||||
int m_longestSyncFFBitOffsetStart;
|
||||
UINT m_initialBitOffset; // debug
|
||||
UINT m_revs; // debug
|
||||
};
|
||||
|
||||
class FloppyDrive
|
||||
|
@ -154,17 +163,18 @@ public:
|
|||
int GetCurrentDrive(void);
|
||||
int GetCurrentTrack(void);
|
||||
float GetCurrentPhase(void);
|
||||
int GetCurrentOffset(void);
|
||||
BYTE GetCurrentLSSBitMask(void);
|
||||
UINT GetCurrentBitOffset(void);
|
||||
double GetCurrentExtraCycles(void);
|
||||
float GetPhase(const int drive);
|
||||
int GetTrack(const int drive);
|
||||
static std::string FormatPhaseString(float phase);
|
||||
static std::string FormatIntFracString(float phase, bool hex);
|
||||
std::string GetCurrentTrackString(void);
|
||||
std::string GetCurrentPhaseString(void);
|
||||
LPCTSTR GetCurrentState(void);
|
||||
bool UserSelectNewDiskImage(const int drive, LPCSTR pszFilename="");
|
||||
bool DriveSwap(void);
|
||||
bool IsDriveConnected(int drive) { return m_floppyDrive[drive].m_isConnected; }
|
||||
void SetFirmware13Sector(void) { m_force13SectorFirmware = true; }
|
||||
|
||||
static const std::string& GetSnapshotCardName(void);
|
||||
virtual void SaveSnapshot(YamlSaveHelper& yamlSaveHelper);
|
||||
|
@ -201,14 +211,20 @@ private:
|
|||
void DataLatchReadWOZ(WORD pc, WORD addr, UINT bitCellRemainder);
|
||||
void DataLoadWriteWOZ(WORD pc, WORD addr, UINT bitCellRemainder);
|
||||
void DataShiftWriteWOZ(WORD pc, WORD addr, ULONG uExecutedCycles);
|
||||
void SetSequencerFunction(WORD addr);
|
||||
void SetSequencerFunction(WORD addr, ULONG executedCycles);
|
||||
void FindTrackSeamWOZ(FloppyDisk& floppy, float track);
|
||||
void DumpTrackWOZ(FloppyDisk floppy);
|
||||
bool GetFirmware(WORD lpNameId, BYTE* pDst);
|
||||
void InitFirmware(LPBYTE pCxRomPeripheral);
|
||||
void UpdateLatchForEmptyDrive(FloppyDrive* pDrive);
|
||||
void InsertSyncEvent(void);
|
||||
static int SyncEventCallback(int id, int cycles, ULONG uExecutedCycles);
|
||||
void ControlStepperDeferred(void);
|
||||
void ControlStepperLogging(WORD address, unsigned __int64 cumulativeCycles);
|
||||
|
||||
void PreJitterCheck(int phase, BYTE latch);
|
||||
void AddJitter(int phase, FloppyDisk& floppy);
|
||||
void AddTrackSeamJitter(float phasePrecise, FloppyDisk& floppy);
|
||||
|
||||
void SaveSnapshotFloppy(YamlSaveHelper& yamlSaveHelper, UINT unit);
|
||||
void SaveSnapshotDriveUnit(YamlSaveHelper& yamlSaveHelper, UINT unit);
|
||||
|
@ -236,6 +252,7 @@ private:
|
|||
BYTE m_13SectorFirmware[DISK2_FW_SIZE];
|
||||
BYTE m_16SectorFirmware[DISK2_FW_SIZE];
|
||||
bool m_is13SectorFirmware;
|
||||
bool m_force13SectorFirmware;
|
||||
|
||||
WORD m_currDrive;
|
||||
FloppyDrive m_floppyDrive[NUM_DRIVES];
|
||||
|
@ -259,7 +276,6 @@ private:
|
|||
// Logic State Sequencer (for WOZ):
|
||||
BYTE m_shiftReg;
|
||||
int m_latchDelay;
|
||||
bool m_resetSequencer;
|
||||
bool m_writeStarted;
|
||||
|
||||
enum SEQFUNC {readSequencing=0, dataShiftWrite, checkWriteProtAndInitWrite, dataLoadWrite}; // UTAIIe 9-14
|
||||
|
@ -276,6 +292,11 @@ private:
|
|||
SEQUENCER_FUNCTION m_seqFunc;
|
||||
UINT m_dbgLatchDelayedCnt;
|
||||
|
||||
bool m_deferredStepperEvent;
|
||||
WORD m_deferredStepperAddress;
|
||||
unsigned __int64 m_deferredStepperCumulativeCycles;
|
||||
SyncEvent m_syncEvent;
|
||||
|
||||
// Jitter (GH#930)
|
||||
static const BYTE m_T00S00Pattern[];
|
||||
UINT m_T00S00PatternIdx;
|
||||
|
|
|
@ -139,3 +139,8 @@ void Disk2CardManager::GetFilenameAndPathForSaveState(std::string& filename, std
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Disk2CardManager::SetStepperDefer(bool defer)
|
||||
{
|
||||
m_stepperDeferred = defer;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class Disk2CardManager
|
||||
{
|
||||
public:
|
||||
Disk2CardManager(void) {}
|
||||
Disk2CardManager(void) : m_stepperDeferred(true) {}
|
||||
~Disk2CardManager(void) {}
|
||||
|
||||
bool IsConditionForFullSpeed(void);
|
||||
|
@ -15,4 +15,9 @@ public:
|
|||
void Destroy(void);
|
||||
bool IsAnyFirmware13Sector(void);
|
||||
void GetFilenameAndPathForSaveState(std::string& filename, std::string& path);
|
||||
void SetStepperDefer(bool defer);
|
||||
bool IsStepperDeferred(void) { return m_stepperDeferred; }
|
||||
|
||||
private:
|
||||
bool m_stepperDeferred; // debug: can disable via cmd-line
|
||||
};
|
||||
|
|
|
@ -273,7 +273,7 @@ void FormatTrack::DecodeLatchNibble(BYTE floppylatch, bool bIsWrite, bool bIsSyn
|
|||
addrPrologue, m_VolTrkSecChk[0], m_VolTrkSecChk[1], m_VolTrkSecChk[2], m_VolTrkSecChk[3], chk?"":"(bad)");
|
||||
if (!m_bSuppressReadD5AAxxDetected)
|
||||
{
|
||||
LOG_DISK("%s\r\n", str);
|
||||
LOG_DISK("%s\r\n", m_strReadD5AAxxDetected.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define LOG_DISK_NIBBLES_USE_RUNTIME_VAR 1
|
||||
#define LOG_DISK_WOZ_LOADWRITE 1
|
||||
#define LOG_DISK_WOZ_SHIFTWRITE 1
|
||||
#define LOG_DISK_WOZ_READTRACK 1
|
||||
#define LOG_DISK_WOZ_TRACK_SEAM 1
|
||||
|
||||
// __VA_ARGS__ not supported on MSVC++ .NET 7.x
|
||||
#if (LOG_DISK_ENABLED)
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
virtual void FrameSetCursorPosByMousePos() = 0;
|
||||
|
||||
virtual void SetFullScreenShowSubunitStatus(bool bShow) = 0;
|
||||
virtual void SetWindowedModeShowDiskiiStatus(bool bShow) = 0;
|
||||
virtual bool GetBestDisplayResolutionForFullScreen(UINT& bestWidth, UINT& bestHeight, UINT userSpecifiedWidth=0, UINT userSpecifiedHeight=0) = 0;
|
||||
virtual int SetViewportScale(int nNewScale, bool bForce = false) = 0;
|
||||
virtual void SetAltEnterToggleFullScreen(bool mode) = 0;
|
||||
|
@ -45,7 +46,7 @@ public:
|
|||
|
||||
// create the network backed for Uthernet 1 and 2
|
||||
// useful to use libslirp in Linux
|
||||
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend() = 0;
|
||||
virtual std::shared_ptr<NetworkBackend> CreateNetworkBackend(const std::string & interfaceName) = 0;
|
||||
|
||||
// FindResource, MAKEINTRESOURCE, SizeofResource, LoadResource, LockResource
|
||||
// Return pointer to resource if size is correct.
|
||||
|
|
|
@ -143,19 +143,12 @@ HarddiskInterfaceCard::HarddiskInterfaceCard(UINT slot) :
|
|||
m_notBusyCycle = 0;
|
||||
|
||||
m_saveDiskImage = true; // Save the DiskImage name to Registry
|
||||
|
||||
// if created by user in Config->Disk, then MemInitializeIO() won't be called
|
||||
if (GetCxRomPeripheral())
|
||||
InitializeIO(GetCxRomPeripheral()); // During regular start-up, Initialize() will be called later by MemInitializeIO()
|
||||
}
|
||||
|
||||
HarddiskInterfaceCard::~HarddiskInterfaceCard(void)
|
||||
{
|
||||
CleanupDriveInternal(HARDDISK_1);
|
||||
CleanupDriveInternal(HARDDISK_2);
|
||||
|
||||
// if destroyed by user in Config->Disk, then ensure that old object's reference is removed
|
||||
UnregisterIoHandler(m_slot);
|
||||
}
|
||||
|
||||
void HarddiskInterfaceCard::Reset(const bool powerCycle)
|
||||
|
@ -469,6 +462,7 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
|
|||
|
||||
CpuCalcCycles(nExecutedCycles);
|
||||
const UINT CYCLES_FOR_DMA_RW_BLOCK = HD_BLOCK_SIZE;
|
||||
const UINT PAGE_SIZE = 256;
|
||||
|
||||
BYTE r = DEVICE_OK;
|
||||
pHDD->m_status_next = DISK_STATUS_READ;
|
||||
|
@ -493,17 +487,15 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
|
|||
case 0x01: //read
|
||||
if ((pHDD->m_diskblock * HD_BLOCK_SIZE) < ImageGetImageSize(pHDD->m_imagehandle))
|
||||
{
|
||||
bool breakpointHit = false;
|
||||
|
||||
bool bRes = ImageReadBlock(pHDD->m_imagehandle, pHDD->m_diskblock, pHDD->m_buf);
|
||||
if (bRes)
|
||||
{
|
||||
pHDD->m_error = 0;
|
||||
r = 0;
|
||||
pCard->m_notBusyCycle = g_nCumulativeCycles + (UINT64)CYCLES_FOR_DMA_RW_BLOCK;
|
||||
pHDD->m_buf_ptr = 0;
|
||||
|
||||
// Apple II's MMU could be setup so that read & write memory is different,
|
||||
// so can't use 'mem' (like we can for HDD block writes)
|
||||
const UINT PAGE_SIZE = 256;
|
||||
WORD dstAddr = pHDD->m_memblock;
|
||||
UINT remaining = HD_BLOCK_SIZE;
|
||||
BYTE* pSrc = pHDD->m_buf;
|
||||
|
@ -518,7 +510,6 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
|
|||
DebuggerBreakOnDmaToOrFromIoMemory(dstAddr, true); // GH#1007
|
||||
//else // Show MessageBox?
|
||||
|
||||
pCard->m_notBusyCycle = 0; // DMA complete
|
||||
bRes = false;
|
||||
break;
|
||||
}
|
||||
|
@ -527,15 +518,26 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
|
|||
UINT size = PAGE_SIZE - (dstAddr & 0xff);
|
||||
if (size > remaining) size = remaining; // clip the last memcpy for the unaligned case
|
||||
|
||||
if (g_nAppMode == MODE_STEPPING)
|
||||
breakpointHit = DebuggerCheckMemBreakpoints(dstAddr, size, true); // GH#1103
|
||||
|
||||
memcpy(page + (dstAddr & 0xff), pSrc, size);
|
||||
pSrc += size;
|
||||
dstAddr += size;
|
||||
dstAddr = (dstAddr + size) & (MEMORY_LENGTH-1); // wraps at 64KiB boundary
|
||||
|
||||
remaining -= size;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bRes)
|
||||
if (bRes)
|
||||
{
|
||||
pHDD->m_error = 0;
|
||||
r = 0;
|
||||
|
||||
if (!breakpointHit)
|
||||
pCard->m_notBusyCycle = g_nCumulativeCycles + (UINT64)CYCLES_FOR_DMA_RW_BLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
pHDD->m_error = 1;
|
||||
r = DEVICE_IO_ERROR;
|
||||
|
@ -552,6 +554,7 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
|
|||
pHDD->m_status_next = DISK_STATUS_WRITE; // or DISK_STATUS_PROT if we ever enable write-protect on HDD
|
||||
bool bRes = true;
|
||||
const bool bAppendBlocks = (pHDD->m_diskblock * HD_BLOCK_SIZE) >= ImageGetImageSize(pHDD->m_imagehandle);
|
||||
bool breakpointHit = false;
|
||||
|
||||
if (bAppendBlocks)
|
||||
{
|
||||
|
@ -578,20 +581,28 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
|
|||
DebuggerBreakOnDmaToOrFromIoMemory(dstAddr, false);
|
||||
//else // Show MessageBox?
|
||||
|
||||
pCard->m_notBusyCycle = 0; // DMA complete
|
||||
bRes = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pHDD->m_memblock <= (MEMORY_LENGTH - HD_BLOCK_SIZE))
|
||||
// NB. Do the writes in units of PAGE_SIZE so that DMA breakpoints are consistent with reads
|
||||
WORD srcAddr = pHDD->m_memblock;
|
||||
UINT remaining = HD_BLOCK_SIZE;
|
||||
BYTE* pDst = pHDD->m_buf;
|
||||
|
||||
while (remaining)
|
||||
{
|
||||
memcpy(pHDD->m_buf, mem + pHDD->m_memblock, HD_BLOCK_SIZE);
|
||||
}
|
||||
else // wraps on 64KiB boundary (GH#1007)
|
||||
{
|
||||
const UINT size = MEMORY_LENGTH - pHDD->m_memblock;
|
||||
memcpy(pHDD->m_buf, mem + pHDD->m_memblock, size);
|
||||
memcpy(pHDD->m_buf + size, mem, HD_BLOCK_SIZE - size);
|
||||
UINT size = PAGE_SIZE - (srcAddr & 0xff);
|
||||
if (size > remaining) size = remaining; // clip the last memcpy for the unaligned case
|
||||
|
||||
if (g_nAppMode == MODE_STEPPING)
|
||||
breakpointHit = DebuggerCheckMemBreakpoints(srcAddr, size, false);
|
||||
|
||||
memcpy(pDst, mem + srcAddr, size);
|
||||
pDst += size;
|
||||
srcAddr = (srcAddr + size) & (MEMORY_LENGTH - 1); // wraps at 64KiB boundary
|
||||
|
||||
remaining -= size;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -602,7 +613,9 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
|
|||
{
|
||||
pHDD->m_error = 0;
|
||||
r = 0;
|
||||
pCard->m_notBusyCycle = g_nCumulativeCycles + (UINT64)CYCLES_FOR_DMA_RW_BLOCK;
|
||||
|
||||
if (!breakpointHit)
|
||||
pCard->m_notBusyCycle = g_nCumulativeCycles + (UINT64)CYCLES_FOR_DMA_RW_BLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -45,6 +45,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "Memory.h"
|
||||
#include "YamlHelper.h"
|
||||
#include "Interface.h"
|
||||
#include "CopyProtectionDongles.h"
|
||||
|
||||
#include "Configuration/PropertySheet.h"
|
||||
|
||||
|
@ -576,6 +577,8 @@ BYTE __stdcall JoyReadButton(WORD pc, WORD address, BYTE, BYTE, ULONG nExecutedC
|
|||
pressed = !swapButtons0and1 ? CheckButton0Pressed() : CheckButton1Pressed();
|
||||
const UINT button0 = !swapButtons0and1 ? 0 : 1;
|
||||
DoAutofire(button0, pressed);
|
||||
if(CopyProtectionDonglePB0() >= 0) //If a copy protection dongle needs PB0, this overrides the joystick
|
||||
pressed = CopyProtectionDonglePB0();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -584,11 +587,15 @@ BYTE __stdcall JoyReadButton(WORD pc, WORD address, BYTE, BYTE, ULONG nExecutedC
|
|||
pressed = !swapButtons0and1 ? CheckButton1Pressed() : CheckButton0Pressed();
|
||||
const UINT button1 = !swapButtons0and1 ? 1 : 0;
|
||||
DoAutofire(button1, pressed);
|
||||
if (CopyProtectionDonglePB1() >= 0) //If a copy protection dongle needs PB1, this overrides the joystick
|
||||
pressed = CopyProtectionDonglePB1();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
if (IS_APPLE2 && (joyinfo[joytype[1]] == DEVICE_NONE))
|
||||
if (CopyProtectionDonglePB2() >= 0) //If a copy protection dongle needs PB2, this overrides the joystick
|
||||
pressed = CopyProtectionDonglePB2();
|
||||
else if (IS_APPLE2 && (joyinfo[joytype[1]] == DEVICE_NONE))
|
||||
{
|
||||
// Apple II/II+ with no joystick has the "SHIFT key mod"
|
||||
// See Sather's Understanding The Apple II p7-36
|
||||
|
@ -665,9 +672,9 @@ void JoyResetPosition(ULONG nExecutedCycles)
|
|||
const UINT joyNum = (pdl & 2) ? 1 : 0;
|
||||
UINT pdlPos = (pdl & 1) ? ypos[joyNum] : xpos[joyNum];
|
||||
|
||||
// This is from KEGS. It helps games like Championship Lode Runner & Boulderdash
|
||||
// This is from KEGS. It helps games like Championship Lode Runner, Boulderdash & Learning with Leeper(GH#1128)
|
||||
if (pdlPos >= 255)
|
||||
pdlPos = 280;
|
||||
pdlPos = 287;
|
||||
|
||||
g_paddleInactiveCycle[pdl] = g_nCumulativeCycles + (UINT64)((double)pdlPos * PDL_CNTR_INTERVAL);
|
||||
}
|
||||
|
|
|
@ -443,7 +443,7 @@ bool Saturn128K::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||
}
|
||||
|
||||
// "Memory Bankxx"
|
||||
std::string memName = GetSnapshotMemStructName() + StrFormat("%02X", uBank);
|
||||
std::string memName = GetSnapshotMemStructName() + ByteToHexStr(uBank);
|
||||
|
||||
if (!yamlLoadHelper.GetSubMap(memName))
|
||||
throw std::runtime_error("Memory: Missing map name: " + memName);
|
||||
|
|
|
@ -56,6 +56,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#include "Tape.h"
|
||||
#include "RGBMonitor.h"
|
||||
#include "VidHD.h"
|
||||
#include "CopyProtectionDongles.h"
|
||||
|
||||
#include "z80emu.h"
|
||||
#include "Z80VICE/z80.h"
|
||||
|
@ -744,7 +745,7 @@ inline bool IsPotentialNoSlotClockAccess(const WORD address)
|
|||
(SW_INTCXROM && (AddrHi == 0xC8)) ); // Internal ROM at [$C100-CFFF] && AddrHi == $C8
|
||||
}
|
||||
|
||||
static bool IsCardInSlot(const UINT uSlot);
|
||||
static bool IsCardInSlot(UINT slot);
|
||||
|
||||
// Enabling expansion ROM ($C800..$CFFF]:
|
||||
// . Enable if: Enable1 && Enable2
|
||||
|
@ -944,7 +945,6 @@ BYTE __stdcall IO_F8xx(WORD programcounter, WORD address, BYTE write, BYTE value
|
|||
|
||||
static struct SlotInfo
|
||||
{
|
||||
bool bHasCard;
|
||||
iofunction IOReadCx;
|
||||
iofunction IOWriteCx;
|
||||
} g_SlotInfo[NUM_SLOTS] = {0};
|
||||
|
@ -977,7 +977,6 @@ static void InitIoHandlers()
|
|||
|
||||
for (i=0; i<NUM_SLOTS; i++)
|
||||
{
|
||||
g_SlotInfo[i].bHasCard = false;
|
||||
g_SlotInfo[i].IOReadCx = IO_Cxxx;
|
||||
g_SlotInfo[i].IOWriteCx = IO_Cxxx;
|
||||
ExpansionRom[i] = NULL;
|
||||
|
@ -990,12 +989,17 @@ void RegisterIoHandler(UINT uSlot, iofunction IOReadC0, iofunction IOWriteC0, io
|
|||
_ASSERT(uSlot < NUM_SLOTS);
|
||||
SlotParameters[uSlot] = lpSlotParameter;
|
||||
|
||||
if (IOReadC0 == NULL) IOReadC0 = IO_Null;
|
||||
if (IOWriteC0 == NULL) IOWriteC0 = IO_Null;
|
||||
|
||||
IORead[uSlot+8] = IOReadC0;
|
||||
IOWrite[uSlot+8] = IOWriteC0;
|
||||
|
||||
if (uSlot == 0) // Don't trash C0xx handlers
|
||||
return;
|
||||
|
||||
//
|
||||
|
||||
if (IOReadCx == NULL) IOReadCx = IO_Cxxx;
|
||||
if (IOWriteCx == NULL) IOWriteCx = IO_Cxxx;
|
||||
|
||||
|
@ -1005,7 +1009,6 @@ void RegisterIoHandler(UINT uSlot, iofunction IOReadC0, iofunction IOWriteC0, io
|
|||
IOWrite[uSlot*16+i] = IOWriteCx;
|
||||
}
|
||||
|
||||
g_SlotInfo[uSlot].bHasCard = true;
|
||||
g_SlotInfo[uSlot].IOReadCx = IOReadCx;
|
||||
g_SlotInfo[uSlot].IOWriteCx = IOWriteCx;
|
||||
|
||||
|
@ -1016,7 +1019,6 @@ void RegisterIoHandler(UINT uSlot, iofunction IOReadC0, iofunction IOWriteC0, io
|
|||
void UnregisterIoHandler(UINT uSlot)
|
||||
{
|
||||
RegisterIoHandler(uSlot, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
g_SlotInfo[uSlot].bHasCard = false;
|
||||
}
|
||||
|
||||
// From UTAIIe:5-28: Since INTCXROM==1 then state of SLOTC3ROM is not important
|
||||
|
@ -1024,7 +1026,7 @@ static void IoHandlerCardsOut(void)
|
|||
{
|
||||
_ASSERT( SW_INTCXROM );
|
||||
|
||||
for (UINT uSlot=1; uSlot<NUM_SLOTS; uSlot++)
|
||||
for (UINT uSlot=SLOT1; uSlot<NUM_SLOTS; uSlot++)
|
||||
{
|
||||
for (UINT i=0; i<16; i++)
|
||||
{
|
||||
|
@ -1034,33 +1036,45 @@ static void IoHandlerCardsOut(void)
|
|||
}
|
||||
}
|
||||
|
||||
// From UTAIIe:5-28: If INTCXROM==0 && SLOTC3ROM==0 Then $C300-C3FF is internal ROM
|
||||
static void IoHandlerSlot3CardOut(void)
|
||||
{
|
||||
_ASSERT(!SW_INTCXROM && !SW_SLOTC3ROM);
|
||||
|
||||
for (UINT i = 0; i < 16; i++)
|
||||
{
|
||||
IORead[SLOT3 * 16 + i] = IO_Cxxx;
|
||||
IOWrite[SLOT3 * 16 + i] = IO_Cxxx;
|
||||
}
|
||||
}
|
||||
|
||||
static void IoHandlerCardsIn(void)
|
||||
{
|
||||
_ASSERT( !SW_INTCXROM );
|
||||
|
||||
for (UINT uSlot=1; uSlot<NUM_SLOTS; uSlot++)
|
||||
for (UINT uSlot=SLOT1; uSlot<NUM_SLOTS; uSlot++)
|
||||
{
|
||||
iofunction ioreadcx = g_SlotInfo[uSlot].IOReadCx;
|
||||
iofunction iowritecx = g_SlotInfo[uSlot].IOWriteCx;
|
||||
|
||||
if (uSlot == 3 && !SW_SLOTC3ROM)
|
||||
if (uSlot == SLOT3 && !SW_SLOTC3ROM)
|
||||
{
|
||||
// From UTAIIe:5-28: If INTCXROM==0 && SLOTC3ROM==0 Then $C300-C3FF is internal ROM
|
||||
ioreadcx = IO_Cxxx;
|
||||
iowritecx = IO_Cxxx;
|
||||
IoHandlerSlot3CardOut();
|
||||
}
|
||||
|
||||
for (UINT i=0; i<16; i++)
|
||||
else
|
||||
{
|
||||
IORead[uSlot*16+i] = ioreadcx;
|
||||
IOWrite[uSlot*16+i] = iowritecx;
|
||||
iofunction ioreadcx = g_SlotInfo[uSlot].IOReadCx;
|
||||
iofunction iowritecx = g_SlotInfo[uSlot].IOWriteCx;
|
||||
|
||||
for (UINT i = 0; i < 16; i++)
|
||||
{
|
||||
IORead[uSlot * 16 + i] = ioreadcx;
|
||||
IOWrite[uSlot * 16 + i] = iowritecx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsCardInSlot(const UINT uSlot)
|
||||
static bool IsCardInSlot(UINT slot)
|
||||
{
|
||||
return g_SlotInfo[uSlot].bHasCard;
|
||||
return GetCardMgr().QuerySlot(slot) != CT_Empty;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -1478,8 +1492,8 @@ bool MemIsAddrCodeMemory(const USHORT addr)
|
|||
|
||||
if (addr <= APPLE_SLOT_END) // [$C100..C7FF]
|
||||
{
|
||||
const UINT uSlot = (addr >> 8) & 0x7;
|
||||
return IsCardInSlot(uSlot);
|
||||
UINT slot = (addr >> 8) & 0x7;
|
||||
return IsCardInSlot(slot);
|
||||
}
|
||||
|
||||
// [$C800..CFFF]
|
||||
|
@ -1744,8 +1758,14 @@ void MemInitializeFromSnapshot(void)
|
|||
//
|
||||
|
||||
// Remove all the cards' ROMs at $Csnn if internal ROM is enabled
|
||||
if (IsAppleIIeOrAbove(GetApple2Type()) && SW_INTCXROM)
|
||||
IoHandlerCardsOut();
|
||||
// Or just $C3nn if SLOT3 ROM is disabled
|
||||
if (IsAppleIIeOrAbove(GetApple2Type()))
|
||||
{
|
||||
if (SW_INTCXROM)
|
||||
IoHandlerCardsOut();
|
||||
else if (!SW_SLOTC3ROM)
|
||||
IoHandlerSlot3CardOut();
|
||||
}
|
||||
|
||||
// Potentially init a card's expansion ROM
|
||||
const UINT uSlot = g_uPeripheralRomSlot;
|
||||
|
@ -2442,7 +2462,7 @@ static void MemLoadSnapshotAuxCommon(YamlLoadHelper& yamlLoadHelper, const std::
|
|||
}
|
||||
|
||||
// "Auxiliary Memory Bankxx"
|
||||
std::string auxMemName = MemGetSnapshotAuxMemStructName() + StrFormat("%02X", uBank-1);
|
||||
std::string auxMemName = MemGetSnapshotAuxMemStructName() + ByteToHexStr(uBank-1);
|
||||
|
||||
if (!yamlLoadHelper.GetSubMap(auxMemName))
|
||||
throw std::runtime_error("Memory: Missing map name: " + auxMemName);
|
||||
|
|
|
@ -546,11 +546,11 @@ BYTE MockingboardCard::IOReadInternal(WORD PC, WORD nAddr, BYTE bWrite, BYTE nVa
|
|||
|
||||
bool bAccessedDevice = (CS & 3) ? true : false;
|
||||
|
||||
bool CS_SSI263 = !(nAddr & 0x80) && (nAddr & 0x60); // SSI263 at $Cn2x and/or $Cn4x
|
||||
bool CS_SSI263 = !(nAddr & 0x10) && (nAddr & 0x60) && !(nAddr & 0x80); // SSI263 at $Cn2x and/or $Cn4x
|
||||
|
||||
if (m_phasorMode == PH_Phasor && CS_SSI263) // NB. Mockingboard mode: SSI263.bit7 not readable
|
||||
{
|
||||
_ASSERT(!bAccessedDevice);
|
||||
_ASSERT(!bAccessedDevice); // In Phasor native mode, 6522 & SSI263 are interleaved in $Cn10-$Cn7F card I/O memory
|
||||
if (nAddr & 0x40) // Primary SSI263
|
||||
nRes = m_MBSubUnit[1].ssi263.Read(nExecutedCycles); // SSI263 only drives bit7
|
||||
if (nAddr & 0x20) // Secondary SSI263
|
||||
|
@ -650,16 +650,19 @@ BYTE MockingboardCard::IOWriteInternal(WORD PC, WORD nAddr, BYTE bWrite, BYTE nV
|
|||
WriteToORB(SY6522_DEVICE_B);
|
||||
}
|
||||
|
||||
bool CS_SSI263 = !(nAddr & 0x80) && (nAddr & 0x60); // SSI263 at $Cn2x and/or $Cn4x
|
||||
bool CS_SSI263_A = (g_phasorMode == PH_Phasor) ? !(nAddr & 0x80) && (nAddr & 0x40) // SSI263 at $Cn4x, $Cn6x
|
||||
: nAddr & 0x40; // SSI263 at $Cn4x-Cn7x, $CnCx-CnFx
|
||||
|
||||
if ((m_phasorMode == PH_Mockingboard || m_phasorMode == PH_Phasor) && CS_SSI263) // No SSI263 for Echo+
|
||||
bool CS_SSI263_B = (g_phasorMode == PH_Phasor) ? !(nAddr & 0x80) && (nAddr & 0x20) // SSI263 at $Cn2x, $Cn6x
|
||||
: nAddr & 0x20; // SSI263 at $Cn2x-Cn3x, $Cn6x-Cn7x, $CnAx-CnBx, $CnEx-CnFx
|
||||
|
||||
if (g_phasorMode == PH_Mockingboard || g_phasorMode == PH_Phasor) // No SSI263 for Echo+
|
||||
{
|
||||
// NB. Mockingboard mode: writes to $Cn4x/SSI263 also get written to 1st 6522 (have confirmed on real Phasor h/w)
|
||||
_ASSERT( (m_phasorMode == PH_Mockingboard && (CS==0 || CS==1)) || (m_phasorMode == PH_Phasor && (CS==0)) );
|
||||
if (nAddr & 0x40) // Primary SSI263
|
||||
m_MBSubUnit[1].ssi263.Write(nAddr&0x7, nValue); // 2nd 6522 is used for 1st speech chip
|
||||
if (nAddr & 0x20) // Secondary SSI263
|
||||
m_MBSubUnit[0].ssi263.Write(nAddr&0x7, nValue); // 1st 6522 is used for 2nd speech chip
|
||||
if (CS_SSI263_A) // Primary SSI263
|
||||
g_MB[1].ssi263.Write(nAddr&0x7, nValue); // 2nd 6522 is used for 1st speech chip
|
||||
if (CS_SSI263_B) // Secondary SSI263
|
||||
g_MB[0].ssi263.Write(nAddr&0x7, nValue); // 1st 6522 is used for 2nd speech chip
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1015,9 +1018,9 @@ UINT MockingboardCard::AY8910_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, BYTE
|
|||
// 7: Added SS_YAML_KEY_SSI263_REG_ACTIVE_PHONEME to SSI263 sub-unit
|
||||
// 8: Moved Timer1 & Timer2 active to 6522 sub-unit
|
||||
// Removed Timer1/Timer2/Speech IRQ Pending
|
||||
// Changed at AppleWin 1.30.8
|
||||
// 9: Phasor AY's are swapped (means that AppleWin 1.30.10 and 1.30.11 are wrong)
|
||||
// Changed at AppleWin 1.30.12
|
||||
const UINT kUNIT_VERSION = 9;
|
||||
|
||||
#define SS_YAML_KEY_MB_UNIT "Unit"
|
||||
#define SS_YAML_KEY_AY_CURR_REG "AY Current Register"
|
||||
|
|
|
@ -111,7 +111,7 @@ Etc.
|
|||
#define MODE_MOUSE_ON (1<<0) // | | | | | | | \--- Mouse off (0) or on (1)
|
||||
#define MODE_INT_MOVEMENT (1<<1) // | | | | | | \----- Interrupt if mouse is moved
|
||||
#define MODE_INT_BUTTON (1<<2) // | | | | | \------- Interrupt if button is pressed
|
||||
#define MODE_INT_VBL (1<<3) // | | | | \--------- Interrupt on VBL
|
||||
#define MODE_INT_VBL (1<<3) // | | | | \--------- Interrupt on VBL [*1]
|
||||
#define MODE_RESERVED4 (1<<4) // | | | \----------- Reserved
|
||||
#define MODE_RESERVED5 (1<<5) // | | \------------- Reserved
|
||||
#define MODE_RESERVED6 (1<<6) // | \--------------- Reserved
|
||||
|
@ -119,6 +119,9 @@ Etc.
|
|||
|
||||
#define MODE_INT_ALL STAT_INT_ALL
|
||||
|
||||
// [*1] "A mode byte of $08 (mouse off but VBL interrupt on) will generate VBL interrupts."
|
||||
// Ref. Apple II Technical Notes - Mouse #3: "Mode Byte of the SetMouse Routine"
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void M6821_Listener_B( void* objTo, BYTE byData )
|
||||
|
@ -449,22 +452,26 @@ void CMouseInterface::OnMouseEvent(bool bEventVBL)
|
|||
{
|
||||
int byState = 0;
|
||||
|
||||
if ( !( m_byMode & MODE_MOUSE_ON ) ) // Mouse Off
|
||||
return;
|
||||
|
||||
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
|
||||
m_byState |= STAT_MOVEMENT_SINCE_READMOUSE; // [TC] Used by CopyII+9.1 and ProTERM3.1
|
||||
}
|
||||
|
||||
if ( m_bBtn0 != m_bButtons[0] || m_bBtn1 != m_bButtons[1] )
|
||||
byState |= STAT_INT_BUTTON; // Button 0/1 interrupt
|
||||
if ( bEventVBL )
|
||||
if ((m_byMode & MODE_INT_VBL) && bEventVBL)
|
||||
byState |= STAT_INT_VBL;
|
||||
|
||||
//byState &= m_byMode & 0x2E;
|
||||
byState &= ((m_byMode & MODE_INT_ALL) | STAT_MOVEMENT_SINCE_READMOUSE); // [TC] Keep "X/Y moved since last READMOUSE" for next MOUSE_READ (Contiki v1.3 uses this)
|
||||
if (m_byMode & MODE_MOUSE_ON)
|
||||
{
|
||||
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
|
||||
m_byState |= STAT_MOVEMENT_SINCE_READMOUSE; // [TC] Used by CopyII+9.1 and ProTERM3.1
|
||||
}
|
||||
|
||||
if (m_bBtn0 != m_bButtons[0] || m_bBtn1 != m_bButtons[1])
|
||||
byState |= STAT_INT_BUTTON; // Button 0/1 interrupt
|
||||
|
||||
byState &= ((m_byMode & MODE_INT_ALL) | STAT_MOVEMENT_SINCE_READMOUSE); // [TC] Keep "X/Y moved since last READMOUSE" for next MOUSE_READ (Contiki v1.3 uses this)
|
||||
}
|
||||
else // if MOUSE OFF then only consider VBL (GH#1138)
|
||||
{
|
||||
byState &= STAT_INT_VBL;
|
||||
}
|
||||
|
||||
if ( byState & STAT_INT_ALL )
|
||||
{
|
||||
|
|
241
source/NTSC.cpp
241
source/NTSC.cpp
|
@ -69,8 +69,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
|
||||
// Globals (Public) ___________________________________________________
|
||||
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 (NB. final hpos is 2 cycles long, so a line is 65 cycles)
|
||||
static uint16_t g_nVideoClockVert = 0; // 9-bit: VC VB VA V5 V4 V3 V2 V1 V0 = 0 .. 262
|
||||
static 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) __________________________________________________
|
||||
static int g_nVideoCharSet = 0;
|
||||
|
@ -113,7 +113,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
static unsigned short (*g_pHorzClockOffset)[VIDEO_SCANNER_MAX_HORZ] = 0;
|
||||
|
||||
typedef void (*UpdateScreenFunc_t)(long);
|
||||
static UpdateScreenFunc_t g_apFuncVideoUpdateScanline[VIDEO_SCANNER_Y_DISPLAY];
|
||||
static UpdateScreenFunc_t g_pFuncUpdateTextScreen = 0; // updateScreenText40;
|
||||
static UpdateScreenFunc_t g_pFuncUpdateGraphicsScreen = 0; // updateScreenText40;
|
||||
static UpdateScreenFunc_t g_pFuncModeSwitchDelayed = 0;
|
||||
|
@ -320,8 +319,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
INLINE void updatePixels( uint16_t bits );
|
||||
INLINE void updateVideoScannerHorzEOL();
|
||||
INLINE void updateVideoScannerAddress();
|
||||
INLINE uint16_t getVideoScannerAddressTXT();
|
||||
INLINE uint16_t getVideoScannerAddressHGR();
|
||||
|
||||
static void initChromaPhaseTables();
|
||||
static real initFilterChroma (real z);
|
||||
|
@ -663,6 +660,12 @@ inline void updateVideoScannerHorzEOLSimple()
|
|||
{
|
||||
if (VIDEO_SCANNER_MAX_HORZ == ++g_nVideoClockHorz)
|
||||
{
|
||||
if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) // Only write to video memory when in visible part of display (GH#1143)
|
||||
{
|
||||
*(uint32_t*)g_pVideoAddress = 0 | ALPHA32_MASK; // VT_COLOR_IDEALIZED: TEXT -> HGR can leave junk on RHS (GH#1106)
|
||||
*(getScanlineNextInbetween()) = 0 | ALPHA32_MASK; // ...and clear junk on RHS for non-'50% Scan lines'
|
||||
}
|
||||
|
||||
g_nVideoClockHorz = 0;
|
||||
|
||||
if (++g_nVideoClockVert == g_videoScannerMaxVert)
|
||||
|
@ -689,15 +692,21 @@ inline void updateVideoScannerHorzEOL()
|
|||
if (!GetColorBurst())
|
||||
{
|
||||
// Only for: VF_TEXT && !VF_MIXED (ie. full 24-row TEXT40 or TEXT80)
|
||||
g_pFuncUpdateBnWPixel(g_nLastColumnPixelNTSC);
|
||||
g_pFuncUpdateBnWPixel(0);
|
||||
g_pFuncUpdateBnWPixel(0);
|
||||
g_pFuncUpdateBnWPixel(g_nLastColumnPixelNTSC); // last pixel in 14M video modes
|
||||
g_pFuncUpdateBnWPixel(0); // 14M ringing pixel! (better definition for 80COL char's right-hand edge)
|
||||
// Direct write instead of g_pFuncUpdateBnWPixel(0) to avoid random pixels on RHS in VT_COLOR_MONITOR_NTSC
|
||||
*(uint32_t*)g_pVideoAddress++ = 0 | ALPHA32_MASK;
|
||||
*(uint32_t*)g_pVideoAddress++ = 0 | ALPHA32_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pFuncUpdateHuePixel(g_nLastColumnPixelNTSC);
|
||||
g_pFuncUpdateHuePixel(0);
|
||||
g_pFuncUpdateHuePixel(0);
|
||||
g_pFuncUpdateHuePixel(g_nLastColumnPixelNTSC); // last pixel in 14M video modes
|
||||
g_pFuncUpdateHuePixel(0); // 14M ringing pixel! (better definition for 80COL char's right-hand edge)
|
||||
// Direct write instead of g_pFuncUpdateHuePixel(0) to avoid random pixels on RHS in VT_COLOR_MONITOR_NTSC
|
||||
*(uint32_t*)g_pVideoAddress = 0 | ALPHA32_MASK;
|
||||
*(getScanlineNextInbetween()) = 0 | ALPHA32_MASK; g_pVideoAddress++; // Clear junk on RHS for TV (Color/B&W) & Monitor (NTSC/PAL). (GH#1157)
|
||||
*(uint32_t*)g_pVideoAddress = 0 | ALPHA32_MASK;
|
||||
*(getScanlineNextInbetween()) = 0 | ALPHA32_MASK; g_pVideoAddress++; // Clear junk on RHS for TV (Color/B&W) & Monitor (NTSC/PAL). (GH#1157)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -738,8 +747,13 @@ inline void updateVideoScannerHorzEOL_SHR()
|
|||
//===========================================================================
|
||||
inline void updateVideoScannerAddress()
|
||||
{
|
||||
if (g_nVideoMixed && g_nVideoClockVert >= VIDEO_SCANNER_Y_MIXED && GetVideo().GetVideoRefreshRate() == VR_50HZ) // GH#763
|
||||
g_nColorBurstPixels = 0; // instantaneously kill color-burst!
|
||||
if (g_nVideoMixed && GetVideo().GetVideoRefreshRate() == VR_50HZ) // GH#763
|
||||
{
|
||||
if (g_nVideoClockVert >= VIDEO_SCANNER_Y_MIXED)
|
||||
g_nColorBurstPixels = 0; // instantaneously kill color-burst!
|
||||
else if (g_nVideoClockVert == 0 && (GetVideo().GetVideoMode() & VF_TEXT) == 0)
|
||||
g_nColorBurstPixels = 1024; // setup for line-0 (when TEXT is off), ie. so GetColorBurst() returns true below (GH#1119)
|
||||
}
|
||||
|
||||
if (g_pFuncUpdateGraphicsScreen == updateScreenSHR)
|
||||
{
|
||||
|
@ -772,11 +786,74 @@ inline void updateVideoScannerAddress()
|
|||
// Centre the older //e video modes when running with a VidHD
|
||||
g_pVideoAddress += GetVideo().GetFrameBufferCentringValue();
|
||||
|
||||
if (GetVideo().HasVidHD())
|
||||
{
|
||||
if (GetVideo().GetVideoType() == VT_COLOR_MONITOR_NTSC)
|
||||
{
|
||||
// EG. Switching between TEXT (full 24 lines) and MIXED (HGR with purple vertical line-0)
|
||||
// - AppleWin-Test repo, Tests-Various.dsk, option-C
|
||||
g_pVideoAddress -= 2;
|
||||
*(uint32_t*)g_pVideoAddress++ = 0 | ALPHA32_MASK;
|
||||
*(uint32_t*)g_pVideoAddress++ = 0 | ALPHA32_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
g_nColorPhaseNTSC = INITIAL_COLOR_PHASE;
|
||||
g_nLastColumnPixelNTSC = 0;
|
||||
g_nSignalBitsNTSC = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
#if 1
|
||||
#define CLEAR_COLOUR_TOP 0
|
||||
#define CLEAR_COLOUR_SIDE 0
|
||||
#else // debug
|
||||
#define CLEAR_COLOUR_TOP 0x0000FF00 // green
|
||||
#define CLEAR_COLOUR_SIDE 0x00FF0000 // red
|
||||
#endif
|
||||
|
||||
static void ClearOverscanVideoArea(void)
|
||||
{
|
||||
if (g_pFuncUpdateGraphicsScreen == updateScreenSHR)
|
||||
return;
|
||||
|
||||
bgra_t* pSaveVideoAddress = g_pVideoAddress; // save g_pVideoAddress
|
||||
g_pVideoAddress = g_pScanLines[0];
|
||||
uint32_t* pLine1Prev = getScanlinePreviousInbetween();
|
||||
g_pVideoAddress = pSaveVideoAddress; // restore g_pVideoAddress
|
||||
|
||||
const int kOverscanOffsetL = 3; // In updateVideoScannerAddress(), g_pVideoAddress could be adjusted by: -2 + -1 = -3
|
||||
const int kOverscanSpanL = 3;
|
||||
const int kOverscanOverlapL = kOverscanSpanL - kOverscanOffsetL;
|
||||
|
||||
const int kOverscanOffsetR = 2;
|
||||
const int kOverscanSpanR = 4; // In updateVideoScannerHorzEOL() it writes 4 extra pixels
|
||||
const int kOverscanOverlapR = kOverscanSpanR - kOverscanOffsetR;
|
||||
|
||||
const int kHorzPixels = (VIDEO_SCANNER_MAX_HORZ - VIDEO_SCANNER_HORZ_START) * 14;
|
||||
|
||||
pLine1Prev += GetVideo().GetFrameBufferCentringValue() - kOverscanOffsetL; // Centre the older //e video modes when running with a VidHD
|
||||
|
||||
// Clear this line at Y=-1
|
||||
for (uint32_t i = 0; i < (kHorzPixels + (kOverscanSpanL - kOverscanOverlapL) + (kOverscanSpanR - kOverscanOverlapR)); i++)
|
||||
*pLine1Prev++ = CLEAR_COLOUR_TOP | ALPHA32_MASK;
|
||||
|
||||
// Clear overscan before & after display area
|
||||
for (uint32_t i = 0; i < VIDEO_SCANNER_Y_DISPLAY*2; i++)
|
||||
{
|
||||
uint32_t* pScanLine = ((uint32_t*)g_pScanLines[i]);
|
||||
pScanLine += GetVideo().GetFrameBufferCentringValue() - kOverscanOffsetL; // Centre the older //e video modes when running with a VidHD
|
||||
|
||||
for (uint32_t j = 0; j < kOverscanSpanL + 1; j++)
|
||||
pScanLine[j] = CLEAR_COLOUR_SIDE | ALPHA32_MASK;
|
||||
|
||||
pScanLine += kOverscanOffsetL + kHorzPixels - kOverscanOffsetR;
|
||||
|
||||
for (uint32_t j = 0; j < kOverscanSpanR; j++)
|
||||
pScanLine[j] = CLEAR_COLOUR_SIDE | ALPHA32_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
INLINE uint16_t getVideoScannerAddressTXT()
|
||||
{
|
||||
|
@ -796,6 +873,29 @@ INLINE uint16_t getVideoScannerAddressHGR()
|
|||
return nAddress;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
INLINE uint16_t getVideoScannerAddressTXTorHGR()
|
||||
{
|
||||
const bool isTextAddr = ((g_nVideoMixed && g_nVideoClockVert >= VIDEO_SCANNER_Y_MIXED) ||
|
||||
(g_uNewVideoModeFlags & VF_TEXT) ||
|
||||
!(g_uNewVideoModeFlags & VF_HIRES));
|
||||
|
||||
if (isTextAddr)
|
||||
return getVideoScannerAddressTXT();
|
||||
else
|
||||
return getVideoScannerAddressHGR();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
INLINE uint16_t getVideoScannerAddressSHR()
|
||||
{
|
||||
// 2 pixels per byte in 320-pixel mode = 160 bytes/scanline
|
||||
// 4 pixels per byte in 640-pixel mode = 160 bytes/scanline
|
||||
const UINT kBytesPerScanline = 160;
|
||||
const UINT kBytesPerCycle = 4;
|
||||
return 0x2000 + kBytesPerScanline * g_nVideoClockVert + kBytesPerCycle * (g_nVideoClockHorz - VIDEO_SCANNER_HORZ_START);
|
||||
}
|
||||
|
||||
// Non-Inline _________________________________________________________
|
||||
|
||||
// Build the 4 phase chroma lookup table
|
||||
|
@ -1749,14 +1849,10 @@ void updateScreenSHR(long cycles6502)
|
|||
{
|
||||
for (; cycles6502 > 0; --cycles6502)
|
||||
{
|
||||
// 2 pixels per byte in 320-pixel mode = 160 bytes/scanline
|
||||
// 4 pixels per byte in 640-pixel mode = 160 bytes/scanline
|
||||
const UINT kBytesPerScanline = 160;
|
||||
const UINT kBytesPerCycle = 4;
|
||||
uint16_t addr = 0x2000 + kBytesPerScanline * g_nVideoClockVert + kBytesPerCycle * (g_nVideoClockHorz - VIDEO_SCANNER_HORZ_START);
|
||||
|
||||
if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY_IIGS)
|
||||
{
|
||||
uint16_t addr = getVideoScannerAddressSHR();
|
||||
|
||||
if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
|
||||
{
|
||||
uint32_t* pAux = (uint32_t*) MemGetAuxPtr(addr); // 8 pixels (320 mode) / 16 pixels (640 mode)
|
||||
|
@ -1836,12 +1932,7 @@ uint16_t NTSC_VideoGetScannerAddress ( const ULONG uExecutedCycles )
|
|||
g_nVideoClockVert = g_videoScannerMaxVert-1;
|
||||
}
|
||||
|
||||
uint16_t addr;
|
||||
bool bHires = (GetVideo().GetVideoMode() & VF_HIRES) && !(GetVideo().GetVideoMode() & VF_TEXT); // SW_HIRES && !SW_TEXT
|
||||
if( bHires )
|
||||
addr = getVideoScannerAddressHGR();
|
||||
else
|
||||
addr = getVideoScannerAddressTXT();
|
||||
uint16_t addr = getVideoScannerAddressTXTorHGR();
|
||||
|
||||
g_nVideoClockVert = currVideoClockVert;
|
||||
g_nVideoClockHorz = currVideoClockHorz;
|
||||
|
@ -1849,10 +1940,19 @@ uint16_t NTSC_VideoGetScannerAddress ( const ULONG uExecutedCycles )
|
|||
return addr;
|
||||
}
|
||||
|
||||
uint16_t NTSC_VideoGetScannerAddressForDebugger(void)
|
||||
void NTSC_GetVideoVertHorzForDebugger(uint16_t& vert, uint16_t& horz)
|
||||
{
|
||||
ResetCyclesExecutedForDebugger(); // if in full-speed, then reset cycles so that CpuCalcCycles() doesn't ASSERT
|
||||
return NTSC_VideoGetScannerAddress(0);
|
||||
NTSC_VideoGetScannerAddress(0);
|
||||
vert = g_nVideoClockVert;
|
||||
horz = g_nVideoClockHorz;
|
||||
}
|
||||
|
||||
uint16_t NTSC_GetVideoVertForDebugger(void)
|
||||
{
|
||||
uint16_t vert, horz;
|
||||
NTSC_GetVideoVertHorzForDebugger(vert, horz);
|
||||
return vert;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -1874,6 +1974,8 @@ void NTSC_SetVideoTextMode( int cols )
|
|||
//===========================================================================
|
||||
void NTSC_SetVideoMode( uint32_t uVideoModeFlags, bool bDelay/*=false*/ )
|
||||
{
|
||||
g_uNewVideoModeFlags = uVideoModeFlags;
|
||||
|
||||
if (uVideoModeFlags & VF_SHR)
|
||||
{
|
||||
g_pFuncUpdateGraphicsScreen = updateScreenSHR;
|
||||
|
@ -1892,7 +1994,6 @@ void NTSC_SetVideoMode( uint32_t uVideoModeFlags, bool bDelay/*=false*/ )
|
|||
// (GH#670) NB. if g_bFullSpeed then NTSC_VideoUpdateCycles() won't be called on the next 6502 opcode.
|
||||
// - Instead it's called when !g_bFullSpeed (eg. drive motor off), then the stale g_uNewVideoModeFlags will get used for NTSC_SetVideoMode()!
|
||||
g_bDelayVideoMode = true;
|
||||
g_uNewVideoModeFlags = uVideoModeFlags;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1952,7 +2053,8 @@ void NTSC_SetVideoMode( uint32_t uVideoModeFlags, bool bDelay/*=false*/ )
|
|||
}
|
||||
else
|
||||
{
|
||||
g_nColorBurstPixels = 1024; // (For mid-line video mode change)
|
||||
if (!g_nVideoMixed || g_nVideoClockVert < VIDEO_SCANNER_Y_MIXED) // 50HZ(PAL) will kill color-burst if 'mixed and >=160' - so don't re-enable color-burst! (GH#1131)
|
||||
g_nColorBurstPixels = 1024; // (For mid-line video mode change)
|
||||
|
||||
// Switching mid-line from TEXT to graphics
|
||||
if (GetVideo().GetVideoType() == VT_COLOR_MONITOR_NTSC &&
|
||||
|
@ -2181,7 +2283,9 @@ _mono:
|
|||
else
|
||||
g_pFuncUpdateBnWPixel = g_pFuncUpdateHuePixel = updatePixelBnWMonitorDoubleScanline;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ClearOverscanVideoArea();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -2632,7 +2736,82 @@ UINT NTSC_GetCyclesUntilVBlank(int cycles)
|
|||
(cyclesPerFrames - cycleCurrentPos + cycleVBl);
|
||||
}
|
||||
|
||||
bool NTSC_GetVblBar(void)
|
||||
{
|
||||
const UINT visibleScanLines = ((g_uNewVideoModeFlags & VF_SHR) == 0) ? VIDEO_SCANNER_Y_DISPLAY : VIDEO_SCANNER_Y_DISPLAY_IIGS;
|
||||
return g_nVideoClockVert < visibleScanLines;
|
||||
}
|
||||
|
||||
bool NTSC_IsVisible(void)
|
||||
{
|
||||
return (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) && (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START);
|
||||
return NTSC_GetVblBar() && (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START);
|
||||
}
|
||||
|
||||
// For debugger
|
||||
uint16_t NTSC_GetScannerAddressAndData(uint32_t& data, int& dataSize)
|
||||
{
|
||||
if (g_uNewVideoModeFlags & VF_SHR)
|
||||
{
|
||||
uint16_t addr = getVideoScannerAddressSHR();
|
||||
uint32_t* pAux = (uint32_t*)MemGetAuxPtr(addr); // 8 pixels (320 mode) / 16 pixels (640 mode)
|
||||
data = pAux[0];
|
||||
dataSize = 4;
|
||||
return addr;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// Copy logic from NTSC_SetVideoMode()
|
||||
if (g_uNewVideoModeFlags & VF_TEXT)
|
||||
{
|
||||
if (g_uNewVideoModeFlags & VF_80COL)
|
||||
dataSize = 2;
|
||||
else
|
||||
dataSize = 1;
|
||||
}
|
||||
else if (g_uNewVideoModeFlags & VF_HIRES)
|
||||
{
|
||||
if (g_uNewVideoModeFlags & VF_DHIRES)
|
||||
{
|
||||
if (g_uNewVideoModeFlags & VF_80COL)
|
||||
dataSize = 2;
|
||||
else
|
||||
dataSize = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataSize = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_uNewVideoModeFlags & VF_DHIRES)
|
||||
{
|
||||
if (g_uNewVideoModeFlags & VF_80COL)
|
||||
dataSize = 2;
|
||||
else
|
||||
dataSize = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataSize = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Extra logic for MIXED mode
|
||||
if (g_nVideoMixed && g_nVideoClockVert >= VIDEO_SCANNER_Y_MIXED && (g_uNewVideoModeFlags & VF_80COL))
|
||||
dataSize = 2;
|
||||
|
||||
uint16_t addr = getVideoScannerAddressTXTorHGR();
|
||||
data = 0;
|
||||
|
||||
if (dataSize == 2)
|
||||
{
|
||||
uint8_t* pAux = MemGetAuxPtr(addr);
|
||||
data = pAux[0] << 8;
|
||||
}
|
||||
uint8_t* pMain = MemGetMainPtr(addr);
|
||||
data |= pMain[0];
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#include "Video.h" // NB. needed by GCC (for fwd enum declaration)
|
||||
|
||||
// Globals (Public)
|
||||
extern uint16_t g_nVideoClockVert;
|
||||
extern uint16_t g_nVideoClockHorz;
|
||||
extern uint32_t g_nChromaSize;
|
||||
|
||||
// Prototypes (Public) ________________________________________________
|
||||
|
@ -14,7 +12,8 @@ void NTSC_SetVideoTextMode(int cols);
|
|||
uint32_t* NTSC_VideoGetChromaTable(bool bHueTypeMonochrome, bool bMonitorTypeColorTV);
|
||||
void NTSC_VideoClockResync(const DWORD dwCyclesThisFrame);
|
||||
uint16_t NTSC_VideoGetScannerAddress(const ULONG uExecutedCycles);
|
||||
uint16_t NTSC_VideoGetScannerAddressForDebugger(void);
|
||||
void NTSC_GetVideoVertHorzForDebugger(uint16_t& vert, uint16_t& horz);
|
||||
uint16_t NTSC_GetVideoVertForDebugger(void);
|
||||
void NTSC_Destroy(void);
|
||||
void NTSC_VideoInit(uint8_t *pFramebuffer);
|
||||
void NTSC_VideoReinitialize(DWORD cyclesThisFrame, bool bInitVideoScannerAddress);
|
||||
|
@ -28,4 +27,6 @@ UINT NTSC_GetCyclesPerFrame(void);
|
|||
UINT NTSC_GetCyclesPerLine(void);
|
||||
UINT NTSC_GetVideoLines(void);
|
||||
UINT NTSC_GetCyclesUntilVBlank(int cycles);
|
||||
bool NTSC_GetVblBar(void);
|
||||
bool NTSC_IsVisible(void);
|
||||
uint16_t NTSC_GetScannerAddressAndData(uint32_t& data, int& dataSize);
|
||||
|
|
|
@ -38,113 +38,99 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#include "../resource/resource.h"
|
||||
|
||||
static DWORD inactivity = 0;
|
||||
static unsigned int g_PrinterIdleLimit = 10;
|
||||
static FILE* file = NULL;
|
||||
DWORD const PRINTDRVR_SIZE = APPLE_SLOT_SIZE;
|
||||
#define DEFAULT_PRINT_FILENAME "Printer.txt"
|
||||
static std::string g_szPrintFilename;
|
||||
bool g_bDumpToPrinter = false;
|
||||
bool g_bConvertEncoding = true;
|
||||
bool g_bFilterUnprintable = true;
|
||||
bool g_bPrinterAppend = false;
|
||||
bool g_bEnableDumpToRealPrinter = false;
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static BYTE __stdcall PrintStatus(WORD, WORD, BYTE, BYTE, ULONG);
|
||||
static BYTE __stdcall PrintTransmit(WORD, WORD, BYTE, BYTE value, ULONG);
|
||||
|
||||
|
||||
|
||||
|
||||
VOID PrintLoadRom(LPBYTE pCxRomPeripheral, const UINT uSlot)
|
||||
void ParallelPrinterCard::InitializeIO(LPBYTE pCxRomPeripheral)
|
||||
{
|
||||
const DWORD PRINTDRVR_SIZE = APPLE_SLOT_SIZE;
|
||||
BYTE* pData = GetFrame().GetResource(IDR_PRINTDRVR_FW, "FIRMWARE", PRINTDRVR_SIZE);
|
||||
if(pData == NULL)
|
||||
return;
|
||||
|
||||
memcpy(pCxRomPeripheral + uSlot*256, pData, PRINTDRVR_SIZE);
|
||||
memcpy(pCxRomPeripheral + m_slot*APPLE_SLOT_SIZE, pData, PRINTDRVR_SIZE);
|
||||
|
||||
//
|
||||
|
||||
RegisterIoHandler(uSlot, PrintStatus, PrintTransmit, NULL, NULL, NULL, NULL);
|
||||
RegisterIoHandler(m_slot, IORead, IOWrite, NULL, NULL, this, NULL);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static BOOL CheckPrint()
|
||||
bool ParallelPrinterCard::CheckPrint(void)
|
||||
{
|
||||
inactivity = 0;
|
||||
if (file == NULL)
|
||||
{
|
||||
m_inactivity = 0;
|
||||
if (m_file == NULL)
|
||||
{
|
||||
//TCHAR filepath[MAX_PATH * 2];
|
||||
//_tcsncpy(filepath, g_sProgramDir, MAX_PATH);
|
||||
//_tcsncat(filepath, _T("Printer.txt"), MAX_PATH);
|
||||
//_tcsncat(filepath, _T("Printer.txt"), MAX_PATH);
|
||||
//file = fopen(filepath, "wb");
|
||||
if (g_bPrinterAppend )
|
||||
file = fopen(Printer_GetFilename().c_str(), "ab");
|
||||
if (m_bPrinterAppend )
|
||||
m_file = fopen(ParallelPrinterCard::GetFilename().c_str(), "ab");
|
||||
else
|
||||
file = fopen(Printer_GetFilename().c_str(), "wb");
|
||||
}
|
||||
return (file != NULL);
|
||||
m_file = fopen(ParallelPrinterCard::GetFilename().c_str(), "wb");
|
||||
}
|
||||
return (m_file != NULL);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static void ClosePrint()
|
||||
void ParallelPrinterCard::ClosePrint(void)
|
||||
{
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
if (m_file != NULL)
|
||||
{
|
||||
fclose(m_file);
|
||||
m_file = NULL;
|
||||
std::string ExtendedFileName = "copy \"";
|
||||
ExtendedFileName.append (Printer_GetFilename());
|
||||
ExtendedFileName.append (ParallelPrinterCard::GetFilename());
|
||||
ExtendedFileName.append ("\" prn");
|
||||
//if (g_bDumpToPrinter) ShellExecute(NULL, "print", Printer_GetFilename(), NULL, NULL, 0); //Print through Notepad
|
||||
if (g_bDumpToPrinter)
|
||||
if (m_bDumpToPrinter)
|
||||
system (ExtendedFileName.c_str ()); //Print through console. This is supposed to be the better way, because it shall print images (with older printers only).
|
||||
|
||||
}
|
||||
inactivity = 0;
|
||||
}
|
||||
m_inactivity = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PrintDestroy()
|
||||
void ParallelPrinterCard::Destroy(void)
|
||||
{
|
||||
ClosePrint();
|
||||
ClosePrint();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PrintUpdate(DWORD totalcycles)
|
||||
void ParallelPrinterCard::Update(const ULONG nExecutedCycles)
|
||||
{
|
||||
if (file == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// if ((inactivity += totalcycles) > (Printer_GetIdleLimit () * 1000 * 1000)) //This line seems to give a very big deviation
|
||||
if ((inactivity += totalcycles) > (Printer_GetIdleLimit () * 710000))
|
||||
{
|
||||
// inactive, so close the file (next print will overwrite or append to it, according to the settings made)
|
||||
ClosePrint();
|
||||
}
|
||||
if (m_file == NULL)
|
||||
return;
|
||||
|
||||
// if ((inactivity += totalcycles) > (Printer_GetIdleLimit () * 1000 * 1000)) //This line seems to give a very big deviation
|
||||
if ((m_inactivity += nExecutedCycles) > (ParallelPrinterCard::GetIdleLimit () * 710000))
|
||||
{
|
||||
// inactive, so close the file (next print will overwrite or append to it, according to the settings made)
|
||||
ClosePrint();
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void PrintReset()
|
||||
void ParallelPrinterCard::Reset(const bool powerCycle)
|
||||
{
|
||||
ClosePrint();
|
||||
ClosePrint();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static BYTE __stdcall PrintStatus(WORD, WORD, BYTE, BYTE, ULONG)
|
||||
BYTE __stdcall ParallelPrinterCard::IORead(WORD, WORD address, BYTE, BYTE, ULONG)
|
||||
{
|
||||
CheckPrint();
|
||||
return 0xFF; // status - TODO?
|
||||
UINT slot = ((address & 0xff) >> 4) - 8;
|
||||
ParallelPrinterCard* card = (ParallelPrinterCard*)MemGetSlotParameters(slot);
|
||||
|
||||
card->CheckPrint();
|
||||
return 0xFF; // status - TODO?
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
static BYTE __stdcall PrintTransmit(WORD, WORD address, BYTE, BYTE value, ULONG)
|
||||
BYTE __stdcall ParallelPrinterCard::IOWrite(WORD, WORD address, BYTE, BYTE value, ULONG)
|
||||
{
|
||||
if (!CheckPrint())
|
||||
UINT slot = ((address & 0xff) >> 4) - 8;
|
||||
ParallelPrinterCard* card = (ParallelPrinterCard*)MemGetSlotParameters(slot);
|
||||
|
||||
if (!card->CheckPrint())
|
||||
return 0;
|
||||
|
||||
// only allow writes to the load output port (i.e., $C090)
|
||||
|
@ -155,44 +141,85 @@ static BYTE __stdcall PrintTransmit(WORD, WORD address, BYTE, BYTE value, ULONG)
|
|||
|
||||
if (IsPravets(GetApple2Type()))
|
||||
{
|
||||
if (g_bConvertEncoding)
|
||||
if (card->m_bConvertEncoding)
|
||||
c = GetPravets().ConvertToPrinterChar(value);
|
||||
}
|
||||
|
||||
if ((g_bFilterUnprintable == false) || (c>31) || (c==13) || (c==10) || (c>0x7F)) //c>0x7F is needed for cyrillic characters
|
||||
fwrite(&c, 1, 1, file);
|
||||
if ((card->m_bFilterUnprintable == false) || (c>31) || (c==13) || (c==10) || (c>0x7F)) //c>0x7F is needed for cyrillic characters
|
||||
fwrite(&c, 1, 1, card->m_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
const std::string & Printer_GetFilename()
|
||||
const std::string& ParallelPrinterCard::GetFilename(void)
|
||||
{
|
||||
return g_szPrintFilename;
|
||||
return m_szPrintFilename;
|
||||
}
|
||||
|
||||
void Printer_SetFilename(const std::string & prtFilename)
|
||||
#define DEFAULT_PRINT_FILENAME "Printer.txt"
|
||||
|
||||
void ParallelPrinterCard::SetFilename(const std::string& prtFilename)
|
||||
{
|
||||
if (!prtFilename.empty())
|
||||
{
|
||||
g_szPrintFilename = prtFilename;
|
||||
m_szPrintFilename = prtFilename;
|
||||
}
|
||||
else //No registry entry is available
|
||||
{
|
||||
g_szPrintFilename = g_sProgramDir + DEFAULT_PRINT_FILENAME;
|
||||
RegSaveString(REG_CONFIG, REGVALUE_PRINTER_FILENAME, 1, g_szPrintFilename);
|
||||
m_szPrintFilename = g_sProgramDir + DEFAULT_PRINT_FILENAME;
|
||||
RegSaveString(REG_CONFIG, REGVALUE_PRINTER_FILENAME, 1, m_szPrintFilename);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int Printer_GetIdleLimit()
|
||||
UINT ParallelPrinterCard::GetIdleLimit(void)
|
||||
{
|
||||
return g_PrinterIdleLimit;
|
||||
return m_printerIdleLimit;
|
||||
}
|
||||
|
||||
void Printer_SetIdleLimit(unsigned int Duration)
|
||||
void ParallelPrinterCard::SetIdleLimit(UINT Duration)
|
||||
{
|
||||
g_PrinterIdleLimit = Duration;
|
||||
m_printerIdleLimit = Duration;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void ParallelPrinterCard::GetRegistryConfig(void)
|
||||
{
|
||||
std::string regSection = RegGetConfigSlotSection(m_slot);
|
||||
|
||||
DWORD dwTmp;
|
||||
char szFilename[MAX_PATH];
|
||||
|
||||
if (RegLoadValue(regSection.c_str(), REGVALUE_DUMP_TO_PRINTER, TRUE, &dwTmp))
|
||||
SetDumpToPrinter(dwTmp ? true : false);
|
||||
|
||||
if (RegLoadValue(regSection.c_str(), REGVALUE_CONVERT_ENCODING, TRUE, &dwTmp))
|
||||
SetConvertEncoding(dwTmp ? true : false);
|
||||
|
||||
if (RegLoadValue(regSection.c_str(), REGVALUE_FILTER_UNPRINTABLE, TRUE, &dwTmp))
|
||||
SetFilterUnprintable(dwTmp ? true : false);
|
||||
|
||||
if (RegLoadValue(regSection.c_str(), REGVALUE_PRINTER_APPEND, TRUE, &dwTmp))
|
||||
SetPrinterAppend(dwTmp ? true : false);
|
||||
|
||||
if (RegLoadString(regSection.c_str(), REGVALUE_PRINTER_FILENAME, 1, szFilename, MAX_PATH, TEXT("")))
|
||||
SetFilename(szFilename);
|
||||
|
||||
if (RegLoadValue(regSection.c_str(), REGVALUE_PRINTER_IDLE_LIMIT, TRUE, &dwTmp))
|
||||
SetIdleLimit(dwTmp);
|
||||
}
|
||||
|
||||
void ParallelPrinterCard::SetRegistryConfig(void)
|
||||
{
|
||||
std::string regSection = RegGetConfigSlotSection(m_slot);
|
||||
RegSaveValue(regSection.c_str(), REGVALUE_DUMP_TO_PRINTER, TRUE, GetDumpToPrinter() ? 1 : 0);
|
||||
RegSaveValue(regSection.c_str(), REGVALUE_CONVERT_ENCODING, TRUE, GetConvertEncoding() ? 1 : 0);
|
||||
RegSaveValue(regSection.c_str(), REGVALUE_FILTER_UNPRINTABLE, TRUE, GetFilterUnprintable() ? 1 : 0);
|
||||
RegSaveValue(regSection.c_str(), REGVALUE_PRINTER_APPEND, TRUE, GetPrinterAppend() ? 1 : 0);
|
||||
RegSaveString(regSection.c_str(), REGVALUE_PRINTER_FILENAME, TRUE, GetFilename());
|
||||
RegSaveValue(regSection.c_str(), REGVALUE_PRINTER_IDLE_LIMIT, TRUE, GetIdleLimit());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -209,57 +236,57 @@ void Printer_SetIdleLimit(unsigned int Duration)
|
|||
#define SS_YAML_KEY_APPEND "Printer Append"
|
||||
#define SS_YAML_KEY_DUMPTOREALPRINTER "Enable Dump To Real Printer"
|
||||
|
||||
const std::string& Printer_GetSnapshotCardName(void)
|
||||
const std::string& ParallelPrinterCard::GetSnapshotCardName(void)
|
||||
{
|
||||
static const std::string name(SS_YAML_VALUE_CARD_PRINTER);
|
||||
return name;
|
||||
}
|
||||
|
||||
void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
|
||||
void ParallelPrinterCard::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper)
|
||||
{
|
||||
YamlSaveHelper::Slot slot(yamlSaveHelper, Printer_GetSnapshotCardName(), uSlot, 1);
|
||||
YamlSaveHelper::Slot slot(yamlSaveHelper, ParallelPrinterCard::GetSnapshotCardName(), m_slot, 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);
|
||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_INACTIVITY, m_inactivity);
|
||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_IDLELIMIT, m_printerIdleLimit);
|
||||
yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, m_szPrintFilename);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_FILEOPEN, (m_file != NULL) ? true : false);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_DUMPTOPRINTER, m_bDumpToPrinter);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_CONVERTENCODING, m_bConvertEncoding);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_FILTERUNPRINTABLE, m_bFilterUnprintable);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_APPEND, m_bPrinterAppend);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_DUMPTOREALPRINTER, m_bEnableDumpToRealPrinter);
|
||||
}
|
||||
|
||||
bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||
bool ParallelPrinterCard::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version)
|
||||
{
|
||||
if (slot != 1) // fixme
|
||||
Card::ThrowErrorInvalidSlot(CT_GenericPrinter, slot);
|
||||
if (m_slot != SLOT1) // fixme
|
||||
Card::ThrowErrorInvalidSlot(CT_GenericPrinter, m_slot);
|
||||
|
||||
if (version != 1)
|
||||
Card::ThrowErrorInvalidVersion(CT_GenericPrinter, version);
|
||||
|
||||
inactivity = yamlLoadHelper.LoadUint(SS_YAML_KEY_INACTIVITY);
|
||||
g_PrinterIdleLimit = yamlLoadHelper.LoadUint(SS_YAML_KEY_IDLELIMIT);
|
||||
g_szPrintFilename = yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME);
|
||||
m_inactivity = yamlLoadHelper.LoadUint(SS_YAML_KEY_INACTIVITY);
|
||||
m_printerIdleLimit = yamlLoadHelper.LoadUint(SS_YAML_KEY_IDLELIMIT);
|
||||
m_szPrintFilename = yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME);
|
||||
|
||||
if (yamlLoadHelper.LoadBool(SS_YAML_KEY_FILEOPEN))
|
||||
{
|
||||
yamlLoadHelper.LoadBool(SS_YAML_KEY_APPEND); // Consume
|
||||
g_bPrinterAppend = true; // Re-open print-file in append mode
|
||||
m_bPrinterAppend = true; // Re-open print-file in append mode
|
||||
BOOL bRes = CheckPrint();
|
||||
if (!bRes)
|
||||
throw std::runtime_error("Printer Card: Unable to resume printing to file");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_bPrinterAppend = yamlLoadHelper.LoadBool(SS_YAML_KEY_APPEND);
|
||||
m_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);
|
||||
m_bDumpToPrinter = yamlLoadHelper.LoadBool(SS_YAML_KEY_DUMPTOPRINTER);
|
||||
m_bConvertEncoding = yamlLoadHelper.LoadBool(SS_YAML_KEY_CONVERTENCODING);
|
||||
m_bFilterUnprintable = yamlLoadHelper.LoadBool(SS_YAML_KEY_FILTERUNPRINTABLE);
|
||||
m_bEnableDumpToRealPrinter = yamlLoadHelper.LoadBool(SS_YAML_KEY_DUMPTOREALPRINTER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,20 +1,69 @@
|
|||
#pragma once
|
||||
|
||||
void PrintDestroy();
|
||||
void PrintLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot);
|
||||
void PrintReset();
|
||||
void PrintUpdate(DWORD);
|
||||
void Printer_SetFilename(const std::string & pszFilename);
|
||||
const std::string & Printer_GetFilename();
|
||||
void Printer_SetIdleLimit(unsigned int Duration);
|
||||
unsigned int Printer_GetIdleLimit();
|
||||
#include "Card.h"
|
||||
#include "Memory.h"
|
||||
|
||||
const std::string& Printer_GetSnapshotCardName(void);
|
||||
void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot);
|
||||
bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||
class ParallelPrinterCard : public Card
|
||||
{
|
||||
public:
|
||||
ParallelPrinterCard(UINT slot) :
|
||||
Card(CT_GenericPrinter, slot)
|
||||
{
|
||||
m_inactivity = 0;
|
||||
m_printerIdleLimit = 10;
|
||||
m_file = NULL;
|
||||
|
||||
extern bool g_bDumpToPrinter;
|
||||
extern bool g_bConvertEncoding;
|
||||
extern bool g_bFilterUnprintable;
|
||||
extern bool g_bPrinterAppend;
|
||||
extern bool g_bEnableDumpToRealPrinter; // Set by cmd-line: -printer-real
|
||||
m_bDumpToPrinter = false;
|
||||
m_bConvertEncoding = false;
|
||||
m_bFilterUnprintable = false;
|
||||
m_bPrinterAppend = false;
|
||||
m_bEnableDumpToRealPrinter = false;
|
||||
}
|
||||
virtual ~ParallelPrinterCard(void) {}
|
||||
|
||||
virtual void Destroy(void);
|
||||
virtual void Reset(const bool powerCycle);
|
||||
virtual void Update(const ULONG nExecutedCycles);
|
||||
virtual void InitializeIO(LPBYTE pCxRomPeripheral);
|
||||
|
||||
static BYTE __stdcall IORead(WORD pc, WORD addr, BYTE bWrite, BYTE value, ULONG nExecutedCycles);
|
||||
static BYTE __stdcall IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE value, ULONG nExecutedCycles);
|
||||
|
||||
static const std::string& GetSnapshotCardName(void);
|
||||
virtual void SaveSnapshot(YamlSaveHelper& yamlSaveHelper);
|
||||
virtual bool LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version);
|
||||
|
||||
const std::string& GetFilename(void);
|
||||
void SetFilename(const std::string& prtFilename);
|
||||
UINT GetIdleLimit(void);
|
||||
void SetIdleLimit(UINT Duration);
|
||||
|
||||
bool GetDumpToPrinter(void) { return m_bDumpToPrinter; }
|
||||
void SetDumpToPrinter(bool value) { m_bDumpToPrinter = value; }
|
||||
bool GetConvertEncoding(void) { return m_bConvertEncoding; }
|
||||
void SetConvertEncoding(bool value) { m_bConvertEncoding = value; }
|
||||
bool GetFilterUnprintable(void) { return m_bFilterUnprintable; }
|
||||
void SetFilterUnprintable(bool value) { m_bFilterUnprintable = value; }
|
||||
bool GetPrinterAppend(void) { return m_bPrinterAppend; }
|
||||
void SetPrinterAppend(bool value) { m_bPrinterAppend = value; }
|
||||
bool GetEnableDumpToRealPrinter(void) { return m_bEnableDumpToRealPrinter; }
|
||||
void SetEnableDumpToRealPrinter(bool value) { m_bEnableDumpToRealPrinter = value; }
|
||||
|
||||
void GetRegistryConfig(void);
|
||||
void SetRegistryConfig(void);
|
||||
|
||||
private:
|
||||
bool CheckPrint(void);
|
||||
void ClosePrint(void);
|
||||
|
||||
DWORD m_inactivity;
|
||||
UINT m_printerIdleLimit;
|
||||
FILE* m_file;
|
||||
std::string m_szPrintFilename;
|
||||
|
||||
bool m_bDumpToPrinter;
|
||||
bool m_bConvertEncoding;
|
||||
bool m_bFilterUnprintable;
|
||||
bool m_bPrinterAppend;
|
||||
bool m_bEnableDumpToRealPrinter; // Set by cmd-line: -printer-real
|
||||
};
|
||||
|
|
|
@ -155,6 +155,9 @@ void RegSaveValue (LPCTSTR section, LPCTSTR key, BOOL peruser, DWORD value) {
|
|||
//===========================================================================
|
||||
static inline std::string RegGetSlotSection(UINT slot)
|
||||
{
|
||||
if (slot == GAME_IO_CONNECTOR)
|
||||
return std::string(REG_CONFIG_GAME_IO_CONNECTOR);
|
||||
|
||||
return (slot == SLOT_AUX)
|
||||
? std::string(REG_CONFIG_SLOT_AUX)
|
||||
: (std::string(REG_CONFIG_SLOT) + (char)('0' + slot));
|
||||
|
@ -197,6 +200,8 @@ void RegDeleteConfigSlotSection(UINT slot)
|
|||
|
||||
void RegSetConfigSlotNewCardType(UINT slot, SS_CARDTYPE type)
|
||||
{
|
||||
_ASSERT(slot != GAME_IO_CONNECTOR);
|
||||
|
||||
RegDeleteConfigSlotSection(slot);
|
||||
|
||||
std::string regSection;
|
||||
|
@ -204,3 +209,17 @@ void RegSetConfigSlotNewCardType(UINT slot, SS_CARDTYPE type)
|
|||
|
||||
RegSaveValue(regSection.c_str(), REGVALUE_CARD_TYPE, TRUE, type);
|
||||
}
|
||||
|
||||
void RegSetConfigGameIOConnectorNewDongleType(UINT slot, DONGLETYPE type)
|
||||
{
|
||||
_ASSERT(slot == GAME_IO_CONNECTOR);
|
||||
if (slot != GAME_IO_CONNECTOR)
|
||||
return;
|
||||
|
||||
RegDeleteConfigSlotSection(slot);
|
||||
|
||||
std::string regSection;
|
||||
regSection = RegGetConfigSlotSection(slot);
|
||||
|
||||
RegSaveValue(regSection.c_str(), REGVALUE_GAME_IO_TYPE, TRUE, type);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "Card.h"
|
||||
#include "CopyProtectionDongles.h"
|
||||
|
||||
#define REGLOAD(a, b) RegLoadValue(TEXT(REG_CONFIG), (a), TRUE, (b))
|
||||
#define REGLOAD_DEFAULT(a, b, c) RegLoadValue(TEXT(REG_CONFIG), (a), TRUE, (b), (c))
|
||||
|
@ -14,4 +15,5 @@ void RegSaveValue (LPCTSTR section, LPCTSTR key, BOOL peruser, DWORD value);
|
|||
|
||||
std::string RegGetConfigSlotSection(UINT slot);
|
||||
void RegDeleteConfigSlotSection(UINT slot);
|
||||
void RegSetConfigSlotNewCardType(UINT slot, enum SS_CARDTYPE type);
|
||||
void RegSetConfigSlotNewCardType(UINT slot, SS_CARDTYPE type);
|
||||
void RegSetConfigGameIOConnectorNewDongleType(UINT slot, DONGLETYPE type);
|
||||
|
|
|
@ -35,12 +35,12 @@ static DWORD dwDataOffset;
|
|||
static DWORD g_dwTotalNumberOfBytesWritten = 0;
|
||||
static unsigned int g_NumChannels = 2;
|
||||
|
||||
int RiffInitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned int NumChannels)
|
||||
bool RiffInitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned int NumChannels)
|
||||
{
|
||||
g_hRiffFile = CreateFile(pszFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
if(g_hRiffFile == INVALID_HANDLE_VALUE)
|
||||
return 1;
|
||||
return false;
|
||||
|
||||
g_NumChannels = NumChannels;
|
||||
|
||||
|
@ -92,13 +92,13 @@ int RiffInitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned in
|
|||
dwDataOffset = SetFilePointer(g_hRiffFile, 0, NULL, FILE_CURRENT);
|
||||
WriteFile(g_hRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int RiffFinishWriteFile()
|
||||
bool RiffFinishWriteFile()
|
||||
{
|
||||
if(g_hRiffFile == INVALID_HANDLE_VALUE)
|
||||
return 1;
|
||||
return false;
|
||||
|
||||
//
|
||||
|
||||
|
@ -114,13 +114,13 @@ int RiffFinishWriteFile()
|
|||
SetFilePointer(g_hRiffFile, dwDataOffset, NULL, FILE_BEGIN);
|
||||
WriteFile(g_hRiffFile, &temp32, 4, &dwNumberOfBytesWritten, NULL);
|
||||
|
||||
return CloseHandle(g_hRiffFile);
|
||||
return CloseHandle(g_hRiffFile) ? true : false;
|
||||
}
|
||||
|
||||
int RiffPutSamples(const short* buf, unsigned int uSamples)
|
||||
bool RiffPutSamples(const short* buf, unsigned int uSamples)
|
||||
{
|
||||
if(g_hRiffFile == INVALID_HANDLE_VALUE)
|
||||
return 1;
|
||||
return false;
|
||||
|
||||
//
|
||||
|
||||
|
@ -135,5 +135,5 @@ int RiffPutSamples(const short* buf, unsigned int uSamples)
|
|||
|
||||
g_dwTotalNumberOfBytesWritten += dwNumberOfBytesWritten;
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
int RiffInitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned int NumChannels);
|
||||
int RiffFinishWriteFile();
|
||||
int RiffPutSamples(const short* buf, unsigned int uSamples);
|
||||
bool RiffInitWriteFile(const char* pszFile, unsigned int sample_rate, unsigned int NumChannels);
|
||||
bool RiffFinishWriteFile(void);
|
||||
bool RiffPutSamples(const short* buf, unsigned int uSamples);
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
Bit 6 = Controller 2, Active Low
|
||||
Bit 7 = Controller 1, Active Low
|
||||
|
||||
Once data is read, button presses (for each controller) should be stored in the following structure
|
||||
Byte 0: B:Y:Sl:St:U:D:L:R
|
||||
Byte 1: A:X:Fl:Fr:x:x:x:x
|
||||
Once data is read, button presses (for each controller) are stored in the following structure:
|
||||
|
||||
The variable controllerXButtons will stored in the reverse order.
|
||||
bit# 16 / 11 10 9 8 / 7 6 5 4 3 2 1 0
|
||||
m_controllerXButtons: *1 x:x:x:x:Fr:Fl:X:A / R:L:D:U:St:Sl:Y:B
|
||||
*1 = Controller plugged in status
|
||||
|
||||
Alex Lukacz Aug 2021
|
||||
*/
|
||||
|
@ -57,6 +57,25 @@
|
|||
#include "Memory.h"
|
||||
#include "YamlHelper.h"
|
||||
|
||||
// Default to Sony DS4 / DualSense:
|
||||
// b11,..,b0: St,Sl / -,-,R,L,X,A,B,Y
|
||||
//
|
||||
// infoEx.dwButtons bit definitions:
|
||||
const UINT SNESMAXCard::m_mainControllerButtons[NUM_BUTTONS] =
|
||||
{
|
||||
Y,B,A,X,LB,RB,UNUSED,UNUSED, SELECT,START,UNUSED,UNUSED,UNUSED,UNUSED,UNUSED,UNUSED // bit0 -> Y, bit1 -> B, bit2 -> A, etc
|
||||
};
|
||||
|
||||
// AltControllerType defaults to "8BitDo NES30 PRO" (can be reconfigured via command line + yaml mapping file)
|
||||
// b11,..,b0: St,Sl,R,L / -,-,-,Y,X,-,B,A
|
||||
//
|
||||
// infoEx.dwButtons bit definitions:
|
||||
UINT SNESMAXCard::m_altControllerButtons[2][NUM_BUTTONS] =
|
||||
{
|
||||
{A,B,UNUSED,X,Y,UNUSED,UNUSED,UNUSED, LB,RB,SELECT,START,UNUSED,UNUSED,UNUSED,UNUSED}, // bit0 -> A, bit1 -> B, bit2 -> unused, etc
|
||||
{A,B,UNUSED,X,Y,UNUSED,UNUSED,UNUSED, LB,RB,SELECT,START,UNUSED,UNUSED,UNUSED,UNUSED}
|
||||
};
|
||||
|
||||
BYTE __stdcall SNESMAXCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE value, ULONG nExecutedCycles)
|
||||
{
|
||||
const UINT slot = ((addr & 0xff) >> 4) - 8;
|
||||
|
@ -100,95 +119,17 @@ BYTE __stdcall SNESMAXCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE value,
|
|||
|
||||
result = joyGetPosEx(JOYSTICKID1, &infoEx);
|
||||
if (result == JOYERR_NOERROR)
|
||||
{
|
||||
xAxis = (infoEx.dwXpos >> 8) & 0xFF;
|
||||
yAxis = (infoEx.dwYpos >> 8) & 0xFF;
|
||||
controller1Buttons = controller1Buttons | ((yAxis < 103 || infoEx.dwPOV == 0 || infoEx.dwPOV == 4500 || infoEx.dwPOV == 31500) << 4); // U Button
|
||||
controller1Buttons = controller1Buttons | ((yAxis > 153 || (infoEx.dwPOV >= 13500 && infoEx.dwPOV <= 22500)) << 5); // D Button
|
||||
controller1Buttons = controller1Buttons | ((xAxis < 103 || (infoEx.dwPOV >= 22500 && infoEx.dwPOV <= 31500)) << 6); // L Button
|
||||
controller1Buttons = controller1Buttons | ((xAxis > 153 || (infoEx.dwPOV >= 4500 && infoEx.dwPOV <= 13500)) << 7); // R Button
|
||||
// controller1Buttons = controller1Buttons | 0 * 0x1000; // spare Button
|
||||
// controller1Buttons = controller1Buttons | 0 * 0x2000; // spare Button
|
||||
// controller1Buttons = controller1Buttons | 0 * 0x4000; // spare Button
|
||||
// controller1Buttons = controller1Buttons | 0 * 0x8000; // spare Button
|
||||
|
||||
if (pCard->m_altControllerType[0])
|
||||
{
|
||||
// 8BitDo NES30 PRO
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0002) >> 1); // B Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0010) >> 3); // Y Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0400) >> 8); // Sl Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0800) >> 8); // St Button
|
||||
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0001) << 8); // A Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0008) << 6); // X Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0100) << 2) | ((infoEx.dwButtons & 0x0040) << 4); // Fl Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0200) << 2) | ((infoEx.dwButtons & 0x0080) << 4); // Fr Button
|
||||
}
|
||||
else
|
||||
{
|
||||
// Logitech F310, Dualshock 4
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0002) >> 1); // B Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0001) << 1); // Y Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0100) >> 6); // Sl Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0200) >> 6); // St Button
|
||||
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0004) << 6); // A Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0008) << 6); // X Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0010) << 6) | ((infoEx.dwButtons & 0x0040) << 4); // Fl Button
|
||||
controller1Buttons = controller1Buttons | ((infoEx.dwButtons & 0x0020) << 6) | ((infoEx.dwButtons & 0x0080) << 4); // Fr Button
|
||||
}
|
||||
controller1Buttons = controller1Buttons | 0x10000; // Controller plugged in status.
|
||||
}
|
||||
controller1Buttons = pCard->GetControllerButtons(JOYSTICKID1, infoEx, pCard->m_altControllerType[0]);
|
||||
controller1Buttons = ~controller1Buttons;
|
||||
|
||||
result = joyGetPosEx(JOYSTICKID2, &infoEx);
|
||||
if (result == JOYERR_NOERROR)
|
||||
{
|
||||
xAxis = (infoEx.dwXpos >> 8) & 0xFF;
|
||||
yAxis = (infoEx.dwYpos >> 8) & 0xFF;
|
||||
controller2Buttons = controller2Buttons | ((yAxis < 103 || infoEx.dwPOV == 0 || infoEx.dwPOV == 4500 || infoEx.dwPOV == 31500) << 4); // U Button
|
||||
controller2Buttons = controller2Buttons | ((yAxis > 153 || (infoEx.dwPOV >= 13500 && infoEx.dwPOV <= 22500)) << 5); // D Button
|
||||
controller2Buttons = controller2Buttons | ((xAxis < 103 || (infoEx.dwPOV >= 22500 && infoEx.dwPOV <= 31500)) << 6); // L Button
|
||||
controller2Buttons = controller2Buttons | ((xAxis > 153 || (infoEx.dwPOV >= 4500 && infoEx.dwPOV <= 13500)) << 7); // R Button
|
||||
// controller2Buttons = controller2Buttons | 0 * 0x1000; // spare Button
|
||||
// controller2Buttons = controller2Buttons | 0 * 0x2000; // spare Button
|
||||
// controller2Buttons = controller2Buttons | 0 * 0x4000; // spare Button
|
||||
// controller2Buttons = controller2Buttons | 0 * 0x8000; // spare Button
|
||||
|
||||
if (pCard->m_altControllerType[1])
|
||||
{
|
||||
// 8BitDo NES30 PRO
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0002) >> 1); // B Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0010) >> 3); // Y Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0400) >> 8); // Sl Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0800) >> 8); // St Button
|
||||
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0001) << 8); // A Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0008) << 6); // X Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0100) << 2) | ((infoEx.dwButtons & 0x0040) << 4); // Fl Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0200) << 2) | ((infoEx.dwButtons & 0x0080) << 4); // Fr Button
|
||||
}
|
||||
else
|
||||
{
|
||||
// Logitech F310, Dualshock 4
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0002) >> 1); // B Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0001) << 1); // Y Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0100) >> 6); // Sl Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0200) >> 6); // St Button
|
||||
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0004) << 6); // A Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0008) << 6); // X Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0010) << 6) | ((infoEx.dwButtons & 0x0040) << 4); // Fl Button
|
||||
controller2Buttons = controller2Buttons | ((infoEx.dwButtons & 0x0020) << 6) | ((infoEx.dwButtons & 0x0080) << 4); // Fr Button
|
||||
}
|
||||
controller2Buttons = controller2Buttons | 0x10000; // Controller plugged in status.
|
||||
}
|
||||
controller2Buttons = pCard->GetControllerButtons(JOYSTICKID2, infoEx, pCard->m_altControllerType[1]);
|
||||
controller2Buttons = ~controller2Buttons;
|
||||
|
||||
break;
|
||||
case 1: // Clock
|
||||
if (pCard->m_buttonIndex <= 16)
|
||||
if (pCard->m_buttonIndex <= NUM_BUTTONS) // NB. 17 bits (where last bit is: Controller plugged in status)
|
||||
{
|
||||
pCard->m_buttonIndex++;
|
||||
controller1Buttons = controller1Buttons >> 1;
|
||||
|
@ -202,11 +143,107 @@ BYTE __stdcall SNESMAXCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE value,
|
|||
return 0;
|
||||
}
|
||||
|
||||
UINT SNESMAXCard::GetControllerButtons(UINT joyNum, JOYINFOEX& infoEx, bool altControllerType)
|
||||
{
|
||||
UINT xAxis = (infoEx.dwXpos >> 8) & 0xFF;
|
||||
UINT yAxis = (infoEx.dwYpos >> 8) & 0xFF;
|
||||
|
||||
UINT controllerButtons = 0;
|
||||
controllerButtons |= ((yAxis < 103 || infoEx.dwPOV == 0 || infoEx.dwPOV == 4500 || infoEx.dwPOV == 31500) << 4); // U Button
|
||||
controllerButtons |= ((yAxis > 153 || (infoEx.dwPOV >= 13500 && infoEx.dwPOV <= 22500)) << 5); // D Button
|
||||
controllerButtons |= ((xAxis < 103 || (infoEx.dwPOV >= 22500 && infoEx.dwPOV <= 31500)) << 6); // L Button
|
||||
controllerButtons |= ((xAxis > 153 || (infoEx.dwPOV >= 4500 && infoEx.dwPOV <= 13500)) << 7); // R Button
|
||||
|
||||
UINT* controllerButtonMappings = !altControllerType ? (UINT*)m_mainControllerButtons : (UINT*)(&m_altControllerButtons[joyNum][0]);
|
||||
|
||||
for (UINT i = 0; i < NUM_BUTTONS; i++)
|
||||
{
|
||||
if (infoEx.dwButtons & (1 << i))
|
||||
{
|
||||
if (controllerButtonMappings[i] != UNUSED)
|
||||
controllerButtons |= (1 << controllerButtonMappings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return controllerButtons | 0x10000; // Controller plugged in status.
|
||||
}
|
||||
|
||||
void SNESMAXCard::InitializeIO(LPBYTE pCxRomPeripheral)
|
||||
{
|
||||
RegisterIoHandler(m_slot, &SNESMAXCard::IORead, &SNESMAXCard::IOWrite, IO_Null, IO_Null, this, NULL);
|
||||
}
|
||||
|
||||
bool SNESMAXCard::ParseControllerMappingFile(UINT joyNum, const char* pathname, std::string& errorMsg)
|
||||
{
|
||||
bool res = true;
|
||||
YamlHelper yamlHelper;
|
||||
|
||||
try
|
||||
{
|
||||
if (!yamlHelper.InitParser(pathname))
|
||||
throw std::runtime_error("Controller mapping file: Failed to initialize parser or open file");
|
||||
|
||||
if (yamlHelper.ParseFileHdr("AppleWin Controller Button Remapping") != 1)
|
||||
throw std::runtime_error("Controller mapping file: Version mismatch");
|
||||
|
||||
std::string scalar;
|
||||
while (yamlHelper.GetScalar(scalar))
|
||||
{
|
||||
if (scalar == SS_YAML_KEY_UNIT)
|
||||
{
|
||||
yamlHelper.GetMapStartEvent();
|
||||
YamlLoadHelper yamlLoadHelper(yamlHelper);
|
||||
std::string hid = yamlLoadHelper.LoadString("HID");
|
||||
std::string desc = yamlLoadHelper.LoadString("Description");
|
||||
for (UINT i = 0; i < SNESMAXCard::NUM_BUTTONS; i++)
|
||||
{
|
||||
char szButtonNum[3] = "00";
|
||||
sprintf_s(szButtonNum, "%d", i + 1); // +1 as 1-based
|
||||
std::string buttonNum = szButtonNum;
|
||||
bool found = false;
|
||||
std::string buttonStr = yamlLoadHelper.LoadString_NoThrow(buttonNum, found);
|
||||
SNESMAXCard::Button button = SNESMAXCard::UNUSED;
|
||||
if (found)
|
||||
{
|
||||
if (buttonStr == "A") button = SNESMAXCard::A;
|
||||
else if (buttonStr == "B") button = SNESMAXCard::B;
|
||||
else if (buttonStr == "X") button = SNESMAXCard::X;
|
||||
else if (buttonStr == "Y") button = SNESMAXCard::Y;
|
||||
else if (buttonStr == "LB") button = SNESMAXCard::LB;
|
||||
else if (buttonStr == "RB") button = SNESMAXCard::RB;
|
||||
else if (buttonStr == "SELECT") button = SNESMAXCard::SELECT;
|
||||
else if (buttonStr == "START") button = SNESMAXCard::START;
|
||||
else if (buttonStr == "") button = SNESMAXCard::UNUSED;
|
||||
else throw std::runtime_error("Controller mapping file: Unknown button: " + buttonStr);
|
||||
}
|
||||
m_altControllerButtons[joyNum][i] = button;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Unknown top-level scalar: " + scalar);
|
||||
}
|
||||
|
||||
break; // TODO: extend to support multiple controllers
|
||||
}
|
||||
}
|
||||
catch (const std::exception& szMessage)
|
||||
{
|
||||
errorMsg = "Error with yaml file: ";
|
||||
errorMsg += pathname;
|
||||
errorMsg += "\n";
|
||||
errorMsg += szMessage.what();
|
||||
res = false;
|
||||
}
|
||||
|
||||
yamlHelper.FinaliseParser();
|
||||
|
||||
if (res)
|
||||
g_cmdLine.snesMaxAltControllerType[joyNum] = true; // Enable the alt controller
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static const UINT kUNIT_VERSION = 1;
|
||||
|
@ -235,8 +272,8 @@ bool SNESMAXCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||
m_buttonIndex = yamlLoadHelper.LoadUint(SS_YAML_KEY_BUTTON_INDEX);
|
||||
|
||||
// Initialise with no buttons pressed (loaded state maybe part way through reading the buttons)
|
||||
m_controller1Buttons = 0xff;
|
||||
m_controller2Buttons = 0xff;
|
||||
m_controller1Buttons = 0x1ffff;
|
||||
m_controller2Buttons = 0x1ffff;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -31,10 +31,18 @@ public:
|
|||
virtual void SaveSnapshot(YamlSaveHelper& yamlSaveHelper);
|
||||
virtual bool LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version);
|
||||
|
||||
static bool ParseControllerMappingFile(UINT joyNum, const char* pathname, std::string& errorMsg);
|
||||
|
||||
private:
|
||||
UINT GetControllerButtons(UINT joyNum, JOYINFOEX& infoEx, bool altControllerType);
|
||||
|
||||
enum Button { B, Y, SELECT, START, U, D, L, R, A, X, LB, RB, UNUSED1, UNUSED2, UNUSED3, UNUSED4, NUM_BUTTONS, UNUSED };
|
||||
|
||||
UINT m_buttonIndex;
|
||||
UINT m_controller1Buttons;
|
||||
UINT m_controller2Buttons;
|
||||
|
||||
static const UINT m_mainControllerButtons[NUM_BUTTONS];
|
||||
bool m_altControllerType[2];
|
||||
static UINT m_altControllerButtons[2][NUM_BUTTONS];
|
||||
};
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user