Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
3b0043af6d
31 changed files with 970 additions and 584 deletions
|
@ -1181,6 +1181,10 @@
|
|||
RelativePath=".\resource\Disk2.rom"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource\Disk2-13sector.rom"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="RESOURCE\DISKOFF.BMP"
|
||||
>
|
||||
|
|
|
@ -9,6 +9,22 @@ https://github.com/AppleWin/AppleWin/issues/new
|
|||
Tom Charlesworth
|
||||
|
||||
|
||||
1.29.10.0 - 13 Feb 2020
|
||||
-----------------------
|
||||
. [PR #756] Write support for WOZ1/WOZ2 images.
|
||||
- Fixes titles that need write support (see: #686, #704, #705).
|
||||
- Allow creation of a blank (WOZ2) image (see AppleWin.chm: 'Creating Disk Images').
|
||||
- multi-file zip support extended to scan for the first valid image.
|
||||
- useful for most woz-a-day multi-file zips which have at least 2 entries and previously needed unzipping.
|
||||
. NB. files in multi-file zips are still write-protected (same for all image types, not just woz).
|
||||
|
||||
|
||||
1.29.9.0 - 26 Jan 2020
|
||||
----------------------
|
||||
. [Bug #752] Fixed double-clicking a registered file-type issue (regression introduced at 1.29.8.0).
|
||||
. [Bug #750] Fixed Ctrl+Alt+Break wasn't emulating CTRL+OA+RESET (regression introduced at 1.29.8.0).
|
||||
|
||||
|
||||
1.29.8.0 - 19 Jan 2020
|
||||
----------------------
|
||||
. [Bug #749] Hotkeys to change emulation speed using Ctrl+n: now ignored if ALT is pressed.
|
||||
|
|
|
@ -98,3 +98,26 @@ N/A
|
|||
5. Clean & build:
|
||||
devenv AppleWinExpress2008.sln /clean
|
||||
cov-build --dir cov-int devenv AppleWinExpress2008.sln /build release
|
||||
|
||||
|
||||
|
||||
|
||||
How to disable F12 so it doesn't trigger a breakpoint
|
||||
=====================================================
|
||||
|
||||
When running AppleWin from Visual Studio (eg. F5), then F12 will trigger a breakpoint.
|
||||
|
||||
This is undesirable, since F12 is used to load a save-state.
|
||||
|
||||
AppleWin doesn't support CTRL+F12 to load a save-state too (for this very reason), but it's possible to disable F12 triggering the breakpoint.
|
||||
|
||||
Background:
|
||||
F12 is the OS's default UserDebuggerHotKey:
|
||||
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc786263(v=ws.10)
|
||||
|
||||
Fix:
|
||||
. Change this Registry key: "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug" to 0x07 (*)
|
||||
. And restart the PC for it to take effect.
|
||||
|
||||
(*) Where 0x07 = Undefined
|
||||
(See: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes)
|
|
@ -1,165 +0,0 @@
|
|||
Setting up CVS for AppleWin
|
||||
Revision 3
|
||||
+ Added pass-phrase, pageant, putty info
|
||||
Revision 2
|
||||
+ Added diff/merge
|
||||
|
||||
|
||||
This is the step-by-step tutorial in getting CVS setup for AppleWin.
|
||||
There are a few steps, but each one is quick and easy to do.
|
||||
|
||||
|
||||
1. Create an account BerliOS
|
||||
http://developer.berlios.de/
|
||||
|
||||
|
||||
2. Download and install TortoiseCVS.
|
||||
a) http://www.tortoisecvs.org/
|
||||
b) Reboot Windows (Grr...)
|
||||
|
||||
You can find a tutorial on how to use TortoiseCVS here:
|
||||
http://cedric.babault.free.fr/TortoiseCVSDoc/UserGuide_en.html
|
||||
|
||||
If you don't want to use TortoiseCVs, you have a few options:
|
||||
|
||||
i) WinCVS (which also has a Mac OS X port, called MacCVS)
|
||||
http://www.wincvs.org/
|
||||
|
||||
ii) cvsnt:
|
||||
http://www.march-hare.com/cvspro/
|
||||
|
||||
|
||||
3. Generate a SSH2 key, using "puttygen"
|
||||
Recommend: using a pass-phrase
|
||||
Recommend: using comment:
|
||||
<username>@shell.berlios.de
|
||||
|
||||
If you installed TortoiseCVS, you will notice it includes an older version of puttygen.exe:
|
||||
i.e.
|
||||
\Program Files\TortoiseCVS\puttygen.exe
|
||||
\Programs\VersionControl\TortoiseCVS\puttygen.exe
|
||||
|
||||
You can find the latest PuTTY here:
|
||||
http://www.chiark.greenend.org.uk/~sgtatham/putty/
|
||||
|
||||
And depending on where you installed it to:
|
||||
C:\Program Files\Putty\puttgygen.exe
|
||||
P:\Programs\Util\Shell\PuTTY\puttygen.exe
|
||||
|
||||
4. In your home directory, make a sub-directory called: .ssh
|
||||
i.e.
|
||||
C:\Document and Settings\<username>\.ssh
|
||||
\users\<username>\.ssh
|
||||
|
||||
|
||||
5. Save your public key into your home directory
|
||||
i.e.
|
||||
<username>\.ssh\identity.pub
|
||||
|
||||
|
||||
6. Save your private key into your home directory
|
||||
i.e.
|
||||
<username>\.ssh\identity
|
||||
|
||||
|
||||
7. Upload your Public SSH key to BerliOS
|
||||
a) http://developer.berlios.de/
|
||||
b) Account Options
|
||||
c) Edit Keys (at bottom of webpage)
|
||||
d) copy from puttygen, and paste into web form
|
||||
e) Verify: CVS/SVN/SSH Shared Keys: 1 <-- was zero
|
||||
|
||||
You will have to use your pass-phrase (may be up to a few hours),
|
||||
until BerliOS recognizes the uploaded ssh2 key.
|
||||
|
||||
|
||||
8. Using Windows Explorer, navigate to the parent directory where you will download AppleWin
|
||||
i.e.
|
||||
<username>\Projects\
|
||||
P:\<username>\Projects\
|
||||
|
||||
|
||||
9. (Optional) Specify a home folder.
|
||||
|
||||
If you have TortoiseCVS installed:
|
||||
a) right Click on any directory
|
||||
b) select CVS
|
||||
c) Preferences.
|
||||
TortoiseCVS should appear.
|
||||
d) Select "Advanced" Tab
|
||||
e) Home Folder: uncheck, always recalculate home folder
|
||||
f) Enter your home directory, for "Custom Home folder"
|
||||
|
||||
|
||||
10. (Optional) Set CVS environment variable: CVS_RSH
|
||||
If you are using TortoiseCVS you can skip this step.
|
||||
(TortoiseCVS uses 'plink' -- command line wrapper for ssh.)
|
||||
|
||||
For other cvs clients, you may need to set CVS_RSH:
|
||||
To set the environment variable "CVS_RSH" to "ssh" (without the quotes):
|
||||
Right-click the My Computer icon on your desktop, Properties, Advanced, Environment variables button.
|
||||
|
||||
|
||||
11. Setting CVSROOT.
|
||||
If you use TortoiseCVS
|
||||
a) right click on the AppleWin Parent directory (the folder where AppleWin will be downloaded to)
|
||||
b) CVS Checkout,
|
||||
and set CVSROOT to:
|
||||
:ext:<username>@cvs.applewin.berlios.de:/cvsroot/applewin
|
||||
|
||||
c) set Module (case sensitive!) to:
|
||||
AppleWin
|
||||
d) select OK, and wait to fetch the complete AppleWin directory.
|
||||
|
||||
Troubleshooting:
|
||||
* You can delete "Previous CVSROOTs":
|
||||
Right click on folder, CVS, Checkout, select appropiate, delete key
|
||||
You will have to press OK for the old entries to be deleted.
|
||||
When you do, a fetch attempt will also be made.
|
||||
* If you enter the wrong init param, you may have to rename / delete your local AppleWin folder!
|
||||
* If you still have problems, you may have to remove the SSH (host) entry from the registry:
|
||||
i.e.
|
||||
HKEY_CURRENT_USER\Software\SimonTatham\Putty\SshHostKeys
|
||||
|
||||
* You shouldn't have to edit, but if you need to, this CVS config file is plain text:
|
||||
AppleWin\CVS\Root
|
||||
|
||||
If you use another cvs client, such as WinCVS, or CVSNT, this may work:
|
||||
:ssh:<username>@cvs.applewin.berlios.de:/cvsroot/applewin
|
||||
|
||||
|
||||
12. You can download a free source-code 'diff' & 'merge' app for win32
|
||||
(which integrates into TortoiseCVS) from here:
|
||||
http://winmerge.sourceforge.net/
|
||||
|
||||
Alternatively you can download a free source-code 'diff' for Win32 here:
|
||||
http://www.prestosoft.com/ps.asp?page=edp_examdiff
|
||||
|
||||
|
||||
13. Start hacking the code!
|
||||
|
||||
|
||||
14. Automatically use your SSH2 key, instead of manually typing your pass-phrase.
|
||||
If you generated a SSH2 private/public key, and have uploaded it to BerliOS,
|
||||
you can tell TortoiseCVS to use your SSH2 key-pair instead of asking for your pass-phrase on every CVS action.
|
||||
|
||||
If you have PuTTY (pageant) installed:
|
||||
a) Run pageant
|
||||
C:\Program Files\PuTTY\pageant.exe
|
||||
|
||||
If you get a configuration error when starting pageant.exe on Win XP, this provides a workaround:
|
||||
http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/xp-wont-run
|
||||
|
||||
b) Right Click on pageant in the system tool bar
|
||||
c) Add key
|
||||
d) Select your private key
|
||||
<username>\.ssh\identity.ppk
|
||||
|
||||
If you have TortoiseCVS installed:
|
||||
a) right Click on any directory
|
||||
b) select CVS
|
||||
c) Preferences.
|
||||
TortoiseCVS should appear.
|
||||
d) Select "Tools" Tab
|
||||
e) To the SSH paramaters, add: -2
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
Setting up SVN for AppleWin
|
||||
===========================
|
||||
|
||||
(This doc assumes you started with cvs_setup.txt)
|
||||
|
||||
|
||||
1. Download and install TortoiseSVN.
|
||||
a) http://tortoisesvn.sourceforge.net/
|
||||
b) Reboot Windows (Grr...)
|
||||
|
||||
==========
|
||||
|
||||
Start by reading the TortoiseSVN help... or just dive right in :)
|
||||
|
||||
|
||||
To browse the svn repository using:
|
||||
a) Web browser (WebSVN) : http://svn.berlios.de/wsvn/applewin
|
||||
b) Windows Explorer: TortoiseSVN -> Repro-browser
|
||||
|
||||
|
||||
Use 'SVN Checkout...' off the right-context menu in a Windows folder.
|
||||
|
||||
URL of repository:
|
||||
http://svn.berlios.de/svnroot/repos/applewin/trunk
|
||||
(to get trunk)
|
||||
|
||||
http://svn.berlios.de/svnroot/repos/applewin
|
||||
(to get everything! Or use [...] to browse for your specific branch)
|
|
@ -89,16 +89,18 @@
|
|||
NB. Using this switch may prevent international keyboards from being able to type certain keys.<br><br>
|
||||
|
||||
-left-alt-control-buttons<br>
|
||||
Use LEFT CONTROL & LEFT ALT for Open Apple & Solid Apple keys respectively.<br><br>
|
||||
Use Left Control & Left Alt for Open Apple & Solid Apple keys respectively.<br>
|
||||
Caveat: Left Control + F2 will do the //e Ctrl+Open Apple+RESET (as Left Control is now both Ctrl and Open Apple!). A workaround is just to use the Right Control key.<br><br>
|
||||
-right-alt-control-buttons<br>
|
||||
Use RIGHT CONTROL & RIGHT ALT for Open Apple & Solid Apple keys respectively.<br><br>
|
||||
Use Right Alt (AltGr) & Right Control for Open Apple & Solid Apple keys respectively.<br>
|
||||
Caveat: Right Control + F2 will do the //e self test (as Right Control is now both Ctrl and Solid Apple!). A workaround is just to use the Left Control key.<br><br>
|
||||
-swap-buttons<br>
|
||||
Swap the Windows keys used for Open Apple & Solid Apple keys.<br><br>
|
||||
|
||||
-use-real-printer<br>
|
||||
Enables Advanced configuration control to allow dumping to a real printer<br><br>
|
||||
-noreg<br>
|
||||
Disable registration of file extensions (.do/.dsk/.nib/.po)<br><br>
|
||||
Disable registration of file extensions (.do/.dsk/.nib/.po/.woz)<br><br>
|
||||
-memclear <n><br>
|
||||
Where n is [0..7]:
|
||||
<ul>
|
||||
|
|
|
@ -78,6 +78,10 @@
|
|||
<param name="Name" value="Save-state Files">
|
||||
<param name="Local" value="savestate.html">
|
||||
</OBJECT>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Command line">
|
||||
<param name="Local" value="CommandLine.html">
|
||||
</OBJECT>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Sound">
|
||||
<param name="Local" value="sound.html">
|
||||
|
@ -101,10 +105,6 @@
|
|||
<param name="Local" value="uthernet-wifi-workaround.html">
|
||||
</OBJECT>
|
||||
</UL>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Command line">
|
||||
<param name="Local" value="CommandLine.html">
|
||||
</OBJECT>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="AppleWin Configuration">
|
||||
<param name="Local" value="configuration.html">
|
||||
|
@ -211,7 +211,7 @@
|
|||
<param name="Local" value="newsgroups.html">
|
||||
</OBJECT>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Internet FTP Sites">
|
||||
<param name="Name" value="Internet Sites">
|
||||
<param name="Local" value="ftp.html">
|
||||
</OBJECT>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
|
|
|
@ -47,9 +47,9 @@ do is make a nibble image of the disk. </p>
|
|||
<p>After nibble copiers became
|
||||
prevalent on
|
||||
the Apple, some software publishers developed tricky new ways of
|
||||
creating disks that even nibble copiers could not copy. It is
|
||||
unlikely that such a disk could be successfully transferred into
|
||||
a disk image. </p>
|
||||
creating disks that even nibble copiers could not copy. Such a
|
||||
disk can only be transferred onto a WOZ disk image using the
|
||||
AppleSauce hardware & software. </p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -63,9 +63,9 @@ Disk Images</a> topic for more information. </p>
|
|||
<p>Please note that not all disk image types supported by
|
||||
AppleWin can be created in this manner. Since there is no way
|
||||
to detect the image type from the image itself, it is determined by the
|
||||
given file extension only. Three extensions are allowed: (.DSK, .DO,
|
||||
.NIB). The first two create a "DOS Order Image" and then latter creates
|
||||
a "Nibble Image". If the extension is completely omitted,
|
||||
given file extension only. Four extensions are allowed: (.DSK, .DO,
|
||||
.NIB, .WOZ). The first two create a "DOS Order Image", .NIB creates
|
||||
a "Nibble Image" and .WOZ creates an empty .WOZ image. If the extension is completely omitted,
|
||||
".DSK" will be chosen by default. For more information, see <a href="ddi-formats.html">Disk Image Formats</a>.</p>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -44,11 +44,22 @@ To do this, click the checkbox for "Open as Read Only" in the Select
|
|||
Disk Image dialog. This works like the physical
|
||||
write-protection mechanism on a real Apple //e floppy disk.</p>
|
||||
|
||||
<p>If a Disk Image name is to
|
||||
<p>If a Disk Image name is too
|
||||
long to read in the Toolbar,
|
||||
simply pause the mouse cursor over a drive button to get a
|
||||
tool-tip with the full name.</p>
|
||||
|
||||
<p>Under the vertical Toolbar, are 2 LEDs, one for each floppy disk drive. The colors indicate drive status:
|
||||
<li>Black: drive is off
|
||||
<li>Green: drive is reading
|
||||
<li>Red: drive is writing
|
||||
<li>Orange: drive is reading (and floppy is write-protected)
|
||||
</p>
|
||||
|
||||
<p>By default the Disk II Controller card has the 16-sector firmware (as used by DOS 3.3 and ProDOS). But if a WOZ image that internally identifies as 13-sector format (eg. DOS 3.2) is put into drive 1, then from the start-up/logo screen (or the next reset), the Disk II Controller card's firmware will automatically be switched to the old 13-sector firmware, allowing the disk to boot. And it will automatically switch back if a non-13-sector WOZ (or any non-WOZ) image is put into drive 1 and the machine is reset.<br>
|
||||
NB. There is no support for this feature for non-WOZ images.
|
||||
</p>
|
||||
|
||||
<p><sub style="FONT-WEIGHT: bold">1</sub> To register the file types in Windows Vista, Windows 7 and Windows 10,
|
||||
you will need to run AppleWin with elevated privileges. This only needs to be done once.
|
||||
Right click the AppleWin.exe icon and select 'Run as Administrator'.</p>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>Internet FTP Sites</title>
|
||||
<title>Internet Sites</title>
|
||||
|
||||
|
||||
</head>
|
||||
|
@ -11,8 +11,7 @@
|
|||
|
||||
<body style="background-color: rgb(255, 255, 255); font-family: verdana;" alink="#008000" link="#008000" vlink="#008000">
|
||||
|
||||
<h2 style="color: rgb(0, 128, 0);">Internet
|
||||
FTP Sites</h2>
|
||||
<h2 style="color: rgb(0, 128, 0);">Internet Sites</h2>
|
||||
|
||||
<hr size="4">
|
||||
<p>Before transferring a program
|
||||
|
@ -23,11 +22,21 @@ typing the word "binary".</p>
|
|||
<p>
|
||||
<a style="font-weight: bold;" target="_blank" href="ftp://public.asimov.net/pub/apple_II/">ftp://public.asimov.net/pub/apple_II/</a><br>
|
||||
|
||||
This site is the largest Apple
|
||||
II emulation site, and the official release point for new
|
||||
versions of AppleWin. Under the /pub/apple_II directory, you will
|
||||
This site is the largest Apple II emulation site. Under the /pub/apple_II directory, you will
|
||||
find disk images, utilities for making your own disk images, and
|
||||
Apple emulators for other computers and operating systems.</p>
|
||||
|
||||
<p>
|
||||
<a style="font-weight: bold;" target="_blank" href="https://archive.org/details/softwarelibrary_apple">https://archive.org/details/softwarelibrary_apple/</a><br>
|
||||
|
||||
This site contains a number of collections of Apple II software. Including:
|
||||
<ul>
|
||||
<li><a style="font-weight: bold;" target="_blank" href="https://archive.org/details/wozaday">https://archive.org/details/wozaday/</a><br>
|
||||
This is an ever expanding collection of Apple II images in WOZ format.<br>
|
||||
<li><a style="font-weight: bold;" target="_blank" href="https://archive.org/details/softwarelibrary_apple_woz">https://archive.org/details/softwarelibrary_apple_woz/</a><br>
|
||||
Another collection of Apple II images in WOZ format.<br>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
full path). This allows you to move your disk image around or distribute them.
|
||||
If AppleWin can't locate the disk image(s), then it will prompt for the new
|
||||
location.</p>
|
||||
<p>NB. Loading of the old v1 file format (.aws file) is still supported.</p>
|
||||
<p>NB. Loading of the old v1 file format (.aws file) is no longer supported. Use AppleWin 1.27.13 to load it at the AppleWin start-up/logo screen,
|
||||
then immediately save it (and it'll be saved in the v2 format).</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
<li><a href="toolbar.html">Using the Toolbar</a>
|
||||
<li><a href="keyboard.html">Using the Keyboard</a>
|
||||
<li><a href="savestate.html">Save-state Files</a>
|
||||
<li><a href="CommandLine.html">Command line</a>
|
||||
<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="CommandLine.html">Command line</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>
|
||||
|
|
|
@ -308,7 +308,8 @@ END
|
|||
// FIRMWARE
|
||||
//
|
||||
|
||||
IDR_DISK2_FW FIRMWARE "Disk2.rom"
|
||||
IDR_DISK2_13SECTOR_FW FIRMWARE "Disk2-13sector.rom"
|
||||
IDR_DISK2_16SECTOR_FW FIRMWARE "Disk2.rom"
|
||||
IDR_SSC_FW FIRMWARE "SSC.rom"
|
||||
IDR_HDDRVR_FW FIRMWARE "Hddrvr.bin"
|
||||
IDR_PRINTDRVR_FW FIRMWARE "Parallel.rom"
|
||||
|
|
BIN
resource/DISK2-13sector.rom
Normal file
BIN
resource/DISK2-13sector.rom
Normal file
Binary file not shown.
|
@ -34,7 +34,6 @@
|
|||
#define IDD_TFE_SETTINGS_DIALOG 131
|
||||
#define IDR_PRINTDRVR_FW 132
|
||||
#define IDD_PROPPAGE_ADVANCED 132
|
||||
#define IDR_DISK2_FW 133
|
||||
#define IDR_SSC_FW 134
|
||||
#define IDR_MOCKINGBOARD_D_FW 135
|
||||
#define IDR_MOUSEINTERFACE_FW 136
|
||||
|
@ -48,6 +47,8 @@
|
|||
#define IDC_CHECK_CONFIRM_REBOOT 146
|
||||
#define IDR_TK3000_2E_ROM 147
|
||||
#define IDR_TKCLOCK_FW 148
|
||||
#define IDR_DISK2_13SECTOR_FW 149
|
||||
#define IDR_DISK2_16SECTOR_FW 150
|
||||
#define IDC_KEYB_BUFFER_ENABLE 1005
|
||||
#define IDC_SAVESTATE 1006
|
||||
#define IDC_SAVESTATE_ON_EXIT 1007
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define APPLEWIN_VERSION 1,29,8,0
|
||||
#define APPLEWIN_VERSION 1,29,10,0
|
||||
|
||||
#define xstr(a) str(a)
|
||||
#define str(a) #a
|
||||
|
|
|
@ -1368,6 +1368,12 @@ static bool ProcessCmdLine(LPSTR lpCmdLine)
|
|||
const std::string strCmdLine(lpCmdLine); // Keep a copy for log ouput
|
||||
std::string strUnsupported;
|
||||
|
||||
// If 1st param looks like an abs pathname then assume that an associated filetype has been double-clicked
|
||||
// NB. Handled by WM_DDE_INITIATE & WM_DDE_EXECUTE msgs
|
||||
if ((lpCmdLine[0] >= '\"' && lpCmdLine[1] >= 'A' && lpCmdLine[1] <= 'Z' && lpCmdLine[2] == ':') // always in quotes
|
||||
|| strncmp("\\\\?\\", lpCmdLine, 4) == 0)
|
||||
return true;
|
||||
|
||||
while (*lpCmdLine)
|
||||
{
|
||||
LPSTR lpNextArg = GetNextArg(lpCmdLine);
|
||||
|
|
|
@ -3768,7 +3768,8 @@ Update_t CmdDisk ( int nArgs)
|
|||
goto _Help;
|
||||
|
||||
char buffer[200] = "";
|
||||
ConsoleBufferPushFormat(buffer, "D%d at T$%s, phase $%s, offset $%X, mask $%02X, extraCycles %.2f, %s",
|
||||
ConsoleBufferPushFormat(buffer, "FW%2d: D%d at T$%s, phase $%s, offset $%X, mask $%02X, extraCycles %.2f, %s",
|
||||
diskCard.GetCurrentFirmware(),
|
||||
diskCard.GetCurrentDrive() + 1,
|
||||
diskCard.GetCurrentTrackString().c_str(),
|
||||
diskCard.GetCurrentPhaseString().c_str(),
|
||||
|
|
297
source/Disk.cpp
297
source/Disk.cpp
|
@ -64,6 +64,7 @@ Disk2InterfaceCard::Disk2InterfaceCard(void) :
|
|||
m_diskLastCycle = 0;
|
||||
m_diskLastReadLatchCycle = 0;
|
||||
m_enhanceDisk = true;
|
||||
m_is13SectorFirmware = false;
|
||||
|
||||
ResetLogicStateSequencer();
|
||||
|
||||
|
@ -228,33 +229,6 @@ void Disk2InterfaceCard::CheckSpinning(const ULONG uExecutedCycles)
|
|||
|
||||
//===========================================================================
|
||||
|
||||
Disk_Status_e Disk2InterfaceCard::GetDriveLightStatus(const int drive)
|
||||
{
|
||||
if (IsDriveValid( drive ))
|
||||
{
|
||||
FloppyDrive* pDrive = &m_floppyDrive[ drive ];
|
||||
|
||||
if (pDrive->m_spinning)
|
||||
{
|
||||
if (pDrive->m_disk.m_bWriteProtected)
|
||||
return DISK_STATUS_PROT;
|
||||
|
||||
if (pDrive->m_writelight)
|
||||
return DISK_STATUS_WRITE;
|
||||
else
|
||||
return DISK_STATUS_READ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DISK_STATUS_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
return DISK_STATUS_OFF;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
bool Disk2InterfaceCard::IsDriveValid(const int drive)
|
||||
{
|
||||
return (drive >= 0 && drive < NUM_DRIVES);
|
||||
|
@ -282,6 +256,12 @@ void Disk2InterfaceCard::ReadTrack(const int drive, ULONG uExecutedCycles)
|
|||
if (ImagePhaseToTrack(pFloppy->m_imagehandle, pDrive->m_phasePrecise, false) >= ImageGetNumTracks(pFloppy->m_imagehandle))
|
||||
{
|
||||
_ASSERT(0); // What can cause this? Add a comment to replace this assert.
|
||||
// Boot with DOS 3.3 Master in D1
|
||||
// Create a blank disk in D2
|
||||
// INIT HELLO,D2
|
||||
// RUN HELLO
|
||||
// F2 to reboot DOS 3.3 Master
|
||||
// RUN HELLO,D2
|
||||
pFloppy->m_trackimagedata = false;
|
||||
return;
|
||||
}
|
||||
|
@ -589,6 +569,31 @@ const std::string & Disk2InterfaceCard::DiskGetFullPathName(const int drive)
|
|||
|
||||
//===========================================================================
|
||||
|
||||
Disk_Status_e Disk2InterfaceCard::GetDriveLightStatus(const int drive)
|
||||
{
|
||||
if (IsDriveValid( drive ))
|
||||
{
|
||||
FloppyDrive* pDrive = &m_floppyDrive[ drive ];
|
||||
|
||||
if (pDrive->m_spinning)
|
||||
{
|
||||
if (pDrive->m_disk.m_bWriteProtected)
|
||||
return DISK_STATUS_PROT;
|
||||
|
||||
if (pDrive->m_writelight)
|
||||
return DISK_STATUS_WRITE;
|
||||
else
|
||||
return DISK_STATUS_READ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DISK_STATUS_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
return DISK_STATUS_OFF;
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::GetLightStatus(Disk_Status_e *pDisk1Status, Disk_Status_e *pDisk2Status)
|
||||
{
|
||||
if (pDisk1Status)
|
||||
|
@ -613,8 +618,8 @@ ImageError_e Disk2InterfaceCard::InsertDisk(const int drive, LPCTSTR pszImageFil
|
|||
pFloppy->clear();
|
||||
|
||||
const DWORD dwAttributes = GetFileAttributes(pszImageFilename);
|
||||
if(dwAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
pFloppy->m_bWriteProtected = false; // Assume this is a new file to create
|
||||
if (dwAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
pFloppy->m_bWriteProtected = false; // Assume this is a new file to create (so it must be write-enabled to allow it to be formatted)
|
||||
else
|
||||
pFloppy->m_bWriteProtected = bForceWriteProtected ? true : (dwAttributes & FILE_ATTRIBUTE_READONLY);
|
||||
|
||||
|
@ -656,6 +661,9 @@ ImageError_e Disk2InterfaceCard::InsertDisk(const int drive, LPCTSTR pszImageFil
|
|||
{
|
||||
GetImageTitle(pszImageFilename, pFloppy->m_imagename, pFloppy->m_fullname);
|
||||
Video_ResetScreenshotCounter(pFloppy->m_imagename);
|
||||
|
||||
if (g_nAppMode == MODE_LOGO)
|
||||
InitFirmware(GetCxRomPeripheral());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -729,17 +737,6 @@ void Disk2InterfaceCard::NotifyInvalidImage(const int drive, LPCTSTR pszImageFil
|
|||
pszImageFilename);
|
||||
break;
|
||||
|
||||
case eIMAGE_ERROR_UNSUPPORTED_MULTI_ZIP:
|
||||
StringCbPrintf(
|
||||
szBuffer,
|
||||
MAX_PATH + 128,
|
||||
TEXT("Unable to use the file %s\nbecause the ")
|
||||
TEXT("first file (%s) in this multi-zip archive is not recognized.\n")
|
||||
TEXT("Try unzipping and using the disk images directly.\n"),
|
||||
pszImageFilename,
|
||||
m_floppyDrive[drive].m_disk.m_strFilenameInZip.c_str());
|
||||
break;
|
||||
|
||||
case eIMAGE_ERROR_GZ:
|
||||
case eIMAGE_ERROR_ZIP:
|
||||
StringCbPrintf(
|
||||
|
@ -984,24 +981,18 @@ void Disk2InterfaceCard::ResetLogicStateSequencer(void)
|
|||
m_shiftReg = 0;
|
||||
m_latchDelay = 0;
|
||||
m_resetSequencer = true;
|
||||
m_writeStarted = false;
|
||||
m_dbgLatchDelayedCnt = 0;
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::UpdateBitStreamPositionAndDiskCycle(const ULONG uExecutedCycles)
|
||||
UINT Disk2InterfaceCard::GetBitCellDelta(const ULONG uExecutedCycles)
|
||||
{
|
||||
FloppyDisk& floppy = m_floppyDrive[m_currDrive].m_disk;
|
||||
|
||||
CpuCalcCycles(uExecutedCycles);
|
||||
const UINT bitCellDelta = GetBitCellDelta(ImageGetOptimalBitTiming(floppy.m_imagehandle));
|
||||
UpdateBitStreamPosition(floppy, bitCellDelta);
|
||||
|
||||
m_diskLastCycle = g_nCumulativeCycles;
|
||||
}
|
||||
|
||||
UINT Disk2InterfaceCard::GetBitCellDelta(const BYTE optimalBitTiming)
|
||||
{
|
||||
FloppyDisk& floppy = m_floppyDrive[m_currDrive].m_disk;
|
||||
|
||||
const BYTE optimalBitTiming = ImageGetOptimalBitTiming(floppy.m_imagehandle);
|
||||
|
||||
// NB. m_extraCycles is needed to retain accuracy:
|
||||
// . Read latch #1: 0-> 9: cycleDelta= 9, bitCellDelta=2, extraCycles=1
|
||||
// . Read latch #2: 9->20: cycleDelta=11, bitCellDelta=2, extraCycles=3
|
||||
|
@ -1010,9 +1001,9 @@ UINT Disk2InterfaceCard::GetBitCellDelta(const BYTE optimalBitTiming)
|
|||
#if 0
|
||||
if (optimalBitTiming == 32)
|
||||
{
|
||||
const ULONG cycleDelta = (ULONG)(g_nCumulativeCycles - m_diskLastCycle) + (BYTE) m_extraCycles;
|
||||
const ULONG cycleDelta = (ULONG)(g_nCumulativeCycles - m_diskLastCycle) + (BYTE) floppy.m_extraCycles;
|
||||
bitCellDelta = cycleDelta / 4; // DIV 4 for 4us per bit-cell
|
||||
m_extraCycles = cycleDelta & 3; // MOD 4 : remainder carried forward for next time
|
||||
floppy.m_extraCycles = cycleDelta & 3; // MOD 4 : remainder carried forward for next time
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -1022,13 +1013,17 @@ UINT Disk2InterfaceCard::GetBitCellDelta(const BYTE optimalBitTiming)
|
|||
bitCellDelta = (UINT) floor( cycleDelta / bitTime );
|
||||
floppy.m_extraCycles = (double)cycleDelta - ((double)bitCellDelta * bitTime);
|
||||
}
|
||||
|
||||
// NB. actual m_diskLastCycle for the last bitCell is minus floppy.m_extraCycles
|
||||
// - but don't need this value; and it's correctly accounted for in this function.
|
||||
m_diskLastCycle = g_nCumulativeCycles;
|
||||
|
||||
return bitCellDelta;
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::UpdateBitStreamPosition(FloppyDisk& floppy, const ULONG bitCellDelta)
|
||||
{
|
||||
_ASSERT(floppy.m_bitCount); // Should never happen - ReadTrack() will handle this
|
||||
if (floppy.m_bitCount == 0)
|
||||
if (floppy.m_bitCount == 0) // Repro: Boot DOS3.3(WOZ), eject+reinsert disk, CALL-151, C0E9 N C0ED ; motor-on & LoadWriteProtect()
|
||||
return;
|
||||
|
||||
floppy.m_bitOffset += bitCellDelta;
|
||||
|
@ -1036,6 +1031,8 @@ void Disk2InterfaceCard::UpdateBitStreamPosition(FloppyDisk& floppy, const ULONG
|
|||
floppy.m_bitOffset %= floppy.m_bitCount;
|
||||
|
||||
UpdateBitStreamOffsets(floppy);
|
||||
|
||||
m_resetSequencer = false;
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::UpdateBitStreamOffsets(FloppyDisk& floppy)
|
||||
|
@ -1045,8 +1042,28 @@ void Disk2InterfaceCard::UpdateBitStreamOffsets(FloppyDisk& floppy)
|
|||
floppy.m_bitMask = 1 << remainder;
|
||||
}
|
||||
|
||||
void __stdcall Disk2InterfaceCard::DataLatchReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles)
|
||||
__forceinline void Disk2InterfaceCard::IncBitStream(FloppyDisk& floppy)
|
||||
{
|
||||
floppy.m_bitMask >>= 1;
|
||||
if (!floppy.m_bitMask)
|
||||
{
|
||||
floppy.m_bitMask = 1 << 7;
|
||||
floppy.m_byte++;
|
||||
}
|
||||
|
||||
floppy.m_bitOffset++;
|
||||
if (floppy.m_bitOffset == floppy.m_bitCount)
|
||||
{
|
||||
floppy.m_bitMask = 1 << 7;
|
||||
floppy.m_bitOffset = 0;
|
||||
floppy.m_byte = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void __stdcall Disk2InterfaceCard::DataLatchReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, ULONG uExecutedCycles)
|
||||
{
|
||||
_ASSERT(m_seqFunc.function != dataShiftWrite);
|
||||
|
||||
FloppyDrive& drive = m_floppyDrive[m_currDrive];
|
||||
FloppyDisk& floppy = drive.m_disk;
|
||||
|
||||
|
@ -1067,14 +1084,11 @@ void __stdcall Disk2InterfaceCard::DataLatchReadWriteWOZ(WORD pc, WORD addr, BYT
|
|||
if (!drive.m_spinning) // GH#599
|
||||
return;
|
||||
|
||||
CpuCalcCycles(uExecutedCycles);
|
||||
|
||||
// Skipping forward a large amount of bitcells means the bitstream will very likely be out-of-sync.
|
||||
// The first 1-bit will produce a latch nibble, and this 1-bit is unlikely to be the nibble's high bit.
|
||||
// So we need to ensure we run enough bits through the sequencer to re-sync.
|
||||
// NB. For Planetfall 13 bitcells(NG) / 14 bitcells(OK)
|
||||
const UINT significantBitCells = 50; // 5x 10-bit sync FF nibbles
|
||||
UINT bitCellDelta = GetBitCellDelta(ImageGetOptimalBitTiming(floppy.m_imagehandle));
|
||||
UINT bitCellDelta = GetBitCellDelta(uExecutedCycles);
|
||||
|
||||
UINT bitCellRemainder;
|
||||
if (bitCellDelta <= significantBitCells)
|
||||
|
@ -1092,20 +1106,21 @@ void __stdcall Disk2InterfaceCard::DataLatchReadWriteWOZ(WORD pc, WORD addr, BYT
|
|||
drive.m_headWindow = 0;
|
||||
}
|
||||
|
||||
// NB. actual m_diskLastCycle for the last bitCell is minus floppy.m_extraCycles
|
||||
// - but don't need this value; and it's correctly accounted for in GetBitCellDelta()
|
||||
m_diskLastCycle = g_nCumulativeCycles;
|
||||
|
||||
if (!bWrite)
|
||||
{
|
||||
if (m_seqFunc.function != readSequencing)
|
||||
{
|
||||
_ASSERT(m_seqFunc.function == checkWriteProtAndInitWrite);
|
||||
UpdateBitStreamPosition(floppy, bitCellRemainder);
|
||||
return;
|
||||
}
|
||||
|
||||
DataLatchReadWOZ(pc, addr, bitCellRemainder);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataLatchWriteWOZ(pc, addr, d, bitCellRemainder);
|
||||
_ASSERT(m_seqFunc.function == dataLoadWrite);
|
||||
DataLoadWriteWOZ(pc, addr, bitCellRemainder);
|
||||
}
|
||||
|
||||
// Show track status (GH#201) - NB. Prevent flooding of forcing UI to redraw!!!
|
||||
|
@ -1147,20 +1162,7 @@ void Disk2InterfaceCard::DataLatchReadWOZ(WORD pc, WORD addr, UINT bitCellRemain
|
|||
BYTE outputBit = (drive.m_headWindow & 0xf) ? (drive.m_headWindow >> 1) & 1
|
||||
: (rand() < (RAND_MAX / 10 * 3)) ? 1 : 0; // ~30% chance of a 1 bit (Ref: WOZ-2.0)
|
||||
|
||||
floppy.m_bitMask >>= 1;
|
||||
if (!floppy.m_bitMask)
|
||||
{
|
||||
floppy.m_bitMask = 1 << 7;
|
||||
floppy.m_byte++;
|
||||
}
|
||||
|
||||
floppy.m_bitOffset++;
|
||||
if (floppy.m_bitOffset == floppy.m_bitCount)
|
||||
{
|
||||
floppy.m_bitMask = 1 << 7;
|
||||
floppy.m_bitOffset = 0;
|
||||
floppy.m_byte = 0;
|
||||
}
|
||||
IncBitStream(floppy);
|
||||
|
||||
if (m_resetSequencer)
|
||||
{
|
||||
|
@ -1238,17 +1240,64 @@ void Disk2InterfaceCard::DataLatchReadWOZ(WORD pc, WORD addr, UINT bitCellRemain
|
|||
#endif
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::DataLatchWriteWOZ(WORD pc, WORD addr, BYTE d, UINT bitCellRemainder)
|
||||
void Disk2InterfaceCard::DataLoadWriteWOZ(WORD pc, WORD addr, UINT bitCellRemainder)
|
||||
{
|
||||
_ASSERT(m_seqFunc.writeMode);
|
||||
_ASSERT(m_seqFunc.function == dataLoadWrite);
|
||||
|
||||
FloppyDrive& drive = m_floppyDrive[m_currDrive];
|
||||
FloppyDisk& floppy = drive.m_disk;
|
||||
|
||||
if (!floppy.m_bWriteProtected)
|
||||
if (floppy.m_bWriteProtected)
|
||||
{
|
||||
//TODO
|
||||
_ASSERT(0); // Must be a bug in the 6502 code for this to occur!
|
||||
UpdateBitStreamPosition(floppy, bitCellRemainder);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_writeStarted)
|
||||
UpdateBitStreamPosition(floppy, bitCellRemainder); // skip over bitCells before switching to write mode
|
||||
|
||||
m_writeStarted = true;
|
||||
#if LOG_DISK_WOZ_LOADWRITE
|
||||
LOG_DISK("load shiftReg with %02X (was: %02X)\n", m_floppyLatch, m_shiftReg);
|
||||
#endif
|
||||
m_shiftReg = m_floppyLatch;
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::DataShiftWriteWOZ(WORD pc, WORD addr, ULONG uExecutedCycles)
|
||||
{
|
||||
_ASSERT(m_seqFunc.function == dataShiftWrite);
|
||||
|
||||
FloppyDrive& drive = m_floppyDrive[m_currDrive];
|
||||
FloppyDisk& floppy = drive.m_disk;
|
||||
|
||||
const UINT bitCellRemainder = GetBitCellDelta(uExecutedCycles);
|
||||
|
||||
if (floppy.m_bWriteProtected)
|
||||
{
|
||||
_ASSERT(0); // Must be a bug in the 6502 code for this to occur!
|
||||
UpdateBitStreamPosition(floppy, bitCellRemainder);
|
||||
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
|
||||
|
||||
for (UINT i = 0; i < bitCellRemainder; i++)
|
||||
{
|
||||
BYTE outputBit = m_shiftReg & 0x80;
|
||||
m_shiftReg <<= 1;
|
||||
|
||||
BYTE n = floppy.m_trackimage[floppy.m_byte];
|
||||
n &= ~floppy.m_bitMask;
|
||||
if (outputBit) n |= floppy.m_bitMask;
|
||||
floppy.m_trackimage[floppy.m_byte] = n;
|
||||
|
||||
IncBitStream(floppy);
|
||||
}
|
||||
|
||||
floppy.m_trackimagedirty = true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -1421,6 +1470,9 @@ void Disk2InterfaceCard::Reset(const bool bIsPowerCycle)
|
|||
|
||||
FrameRefreshStatus(DRAW_LEDS, false);
|
||||
}
|
||||
|
||||
InitFirmware(GetCxRomPeripheral());
|
||||
FrameRefreshStatus(DRAW_TITLE, false);
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::ResetSwitches(void)
|
||||
|
@ -1485,7 +1537,9 @@ bool Disk2InterfaceCard::UserSelectNewDiskImage(const int drive, LPCSTR pszFilen
|
|||
|
||||
void __stdcall Disk2InterfaceCard::LoadWriteProtect(WORD, WORD, BYTE write, BYTE value, ULONG uExecutedCycles)
|
||||
{
|
||||
// NB. m_seqFunc.function == checkWriteProtAndInitWrite or shiftWrite (both OK)
|
||||
// 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)
|
||||
|
@ -1500,20 +1554,28 @@ void __stdcall Disk2InterfaceCard::LoadWriteProtect(WORD, WORD, BYTE write, BYTE
|
|||
// 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)
|
||||
// . A read or write will shift 'write protect' in QA.
|
||||
if (m_floppyDrive[m_currDrive].m_disk.m_bWriteProtected)
|
||||
FloppyDisk& floppy = m_floppyDrive[m_currDrive].m_disk;
|
||||
if (floppy.m_bWriteProtected)
|
||||
m_floppyLatch |= 0x80;
|
||||
else
|
||||
m_floppyLatch &= 0x7F;
|
||||
|
||||
if (ImageIsWOZ(m_floppyDrive[m_currDrive].m_disk.m_imagehandle))
|
||||
if (m_writeStarted) // Prevent ResetLogicStateSequencer() from resetting m_writeStarted
|
||||
return;
|
||||
|
||||
if (ImageIsWOZ(floppy.m_imagehandle))
|
||||
{
|
||||
#if LOG_DISK_NIBBLES_READ
|
||||
CpuCalcCycles(uExecutedCycles);
|
||||
LOG_DISK("%08X: reset LSS: ~PC=%04X\r\n", (UINT32)g_nCumulativeCycles, regs.pc);
|
||||
#endif
|
||||
|
||||
const UINT bitCellDelta = GetBitCellDelta(uExecutedCycles);
|
||||
UpdateBitStreamPosition(floppy, bitCellDelta); // Fix E7-copy protection
|
||||
|
||||
// UpdateBitStreamPosition() must be done below ResetLSS, as the former clears m_resetSequencer.
|
||||
// . 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)
|
||||
// m_latchDelay = 7; // TODO: Treat like a regular $C0EC latch load?
|
||||
UpdateBitStreamPositionAndDiskCycle(uExecutedCycles); // Fix E7-copy protection
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1639,28 +1701,51 @@ bool Disk2InterfaceCard::DriveSwap(void)
|
|||
|
||||
//===========================================================================
|
||||
|
||||
// TODO: LoadRom_Disk_Floppy()
|
||||
void Disk2InterfaceCard::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot)
|
||||
bool Disk2InterfaceCard::GetFirmware(LPCSTR lpName, BYTE* pDst)
|
||||
{
|
||||
const UINT DISK2_FW_SIZE = APPLE_SLOT_SIZE;
|
||||
|
||||
HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_DISK2_FW), "FIRMWARE");
|
||||
HRSRC hResInfo = FindResource(NULL, lpName, "FIRMWARE");
|
||||
if(hResInfo == NULL)
|
||||
return;
|
||||
return false;
|
||||
|
||||
DWORD dwResSize = SizeofResource(NULL, hResInfo);
|
||||
if(dwResSize != DISK2_FW_SIZE)
|
||||
return;
|
||||
return false;
|
||||
|
||||
HGLOBAL hResData = LoadResource(NULL, hResInfo);
|
||||
if(hResData == NULL)
|
||||
return;
|
||||
return false;
|
||||
|
||||
BYTE* pData = (BYTE*) LockResource(hResData); // NB. Don't need to unlock resource
|
||||
if(pData == NULL)
|
||||
if (!pData)
|
||||
return false;
|
||||
|
||||
memcpy(pDst, pData, DISK2_FW_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Disk2InterfaceCard::InitFirmware(LPBYTE pCxRomPeripheral)
|
||||
{
|
||||
if (pCxRomPeripheral == NULL)
|
||||
return;
|
||||
|
||||
memcpy(pCxRomPeripheral + uSlot*APPLE_SLOT_SIZE, pData, DISK2_FW_SIZE);
|
||||
ImageInfo* pImage = m_floppyDrive[DRIVE_1].m_disk.m_imagehandle;
|
||||
|
||||
m_is13SectorFirmware = ImageIsBootSectorFormatSector13(pImage);
|
||||
|
||||
if (m_is13SectorFirmware)
|
||||
memcpy(pCxRomPeripheral + m_slot*APPLE_SLOT_SIZE, m_13SectorFirmware, DISK2_FW_SIZE);
|
||||
else
|
||||
memcpy(pCxRomPeripheral + m_slot*APPLE_SLOT_SIZE, m_16SectorFirmware, DISK2_FW_SIZE);
|
||||
}
|
||||
|
||||
// TODO: LoadRom_Disk_Floppy()
|
||||
void Disk2InterfaceCard::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot)
|
||||
{
|
||||
bool res = GetFirmware(MAKEINTRESOURCE(IDR_DISK2_13SECTOR_FW), m_13SectorFirmware);
|
||||
_ASSERT(res);
|
||||
|
||||
res = GetFirmware(MAKEINTRESOURCE(IDR_DISK2_16SECTOR_FW), m_16SectorFirmware);
|
||||
_ASSERT(res);
|
||||
|
||||
// Note: We used to disable the track stepping delay in the Disk II controller firmware by
|
||||
// patching $C64C with $A9,$00,$EA. Now not doing this since:
|
||||
|
@ -1672,6 +1757,8 @@ void Disk2InterfaceCard::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot)
|
|||
RegisterIoHandler(uSlot, &Disk2InterfaceCard::IORead, &Disk2InterfaceCard::IOWrite, NULL, NULL, this, NULL);
|
||||
|
||||
m_slot = uSlot;
|
||||
|
||||
InitFirmware(pCxRomPeripheral);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -1688,6 +1775,9 @@ void Disk2InterfaceCard::SetSequencerFunction(WORD addr)
|
|||
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)
|
||||
}
|
||||
|
||||
if (!m_seqFunc.writeMode)
|
||||
m_writeStarted = false;
|
||||
}
|
||||
|
||||
BYTE __stdcall Disk2InterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles)
|
||||
|
@ -1698,6 +1788,9 @@ BYTE __stdcall Disk2InterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE
|
|||
ImageInfo* pImage = pCard->m_floppyDrive[pCard->m_currDrive].m_disk.m_imagehandle;
|
||||
bool isWOZ = ImageIsWOZ(pImage);
|
||||
|
||||
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);
|
||||
|
||||
switch (addr & 0xF)
|
||||
|
@ -1723,8 +1816,8 @@ BYTE __stdcall Disk2InterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE
|
|||
// only even addresses return the latch (UTAIIe Table 9.1)
|
||||
if (!(addr & 1))
|
||||
{
|
||||
if (isWOZ)
|
||||
pCard->DataLatchReadWriteWOZ(pc, addr, bWrite, d, nExecutedCycles);
|
||||
if (isWOZ && pCard->m_seqFunc.function != dataShiftWrite)
|
||||
pCard->DataLatchReadWriteWOZ(pc, addr, bWrite, nExecutedCycles);
|
||||
|
||||
return pCard->m_floppyLatch;
|
||||
}
|
||||
|
@ -1740,6 +1833,9 @@ BYTE __stdcall Disk2InterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE
|
|||
ImageInfo* pImage = pCard->m_floppyDrive[pCard->m_currDrive].m_disk.m_imagehandle;
|
||||
bool isWOZ = ImageIsWOZ(pImage);
|
||||
|
||||
if (isWOZ && pCard->m_seqFunc.function == dataShiftWrite)
|
||||
pCard->DataShiftWriteWOZ(pc, addr, nExecutedCycles); // Finish any previous write
|
||||
|
||||
pCard->SetSequencerFunction(addr);
|
||||
|
||||
switch (addr & 0xF)
|
||||
|
@ -1763,13 +1859,12 @@ BYTE __stdcall Disk2InterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE
|
|||
}
|
||||
|
||||
// any address writes the latch via sequencer LD command (74LS323 datasheet)
|
||||
// if (pCard->m_seqFunc.writeMode /* && m_seqFunc.loadMode */)
|
||||
if (pCard->m_seqFunc.function == dataLoadWrite)
|
||||
{
|
||||
pCard->m_floppyLatch = d;
|
||||
|
||||
if (isWOZ)
|
||||
pCard->DataLatchReadWriteWOZ(pc, addr, bWrite, d, nExecutedCycles);
|
||||
pCard->DataLatchReadWriteWOZ(pc, addr, bWrite, nExecutedCycles);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -144,6 +144,7 @@ public:
|
|||
void NotifyInvalidImage(const int drive, LPCTSTR pszImageFilename, const ImageError_e Error);
|
||||
bool GetProtect(const int drive);
|
||||
void SetProtect(const int drive, const bool bWriteProtect);
|
||||
UINT GetCurrentFirmware(void) { return m_is13SectorFirmware ? 13 : 16; }
|
||||
int GetCurrentDrive(void);
|
||||
int GetCurrentTrack(void);
|
||||
float GetCurrentPhase(void);
|
||||
|
@ -185,15 +186,18 @@ private:
|
|||
void WriteTrack(const int drive);
|
||||
const std::string & DiskGetFullPathName(const int drive);
|
||||
void ResetLogicStateSequencer(void);
|
||||
void UpdateBitStreamPositionAndDiskCycle(const ULONG uExecutedCycles);
|
||||
UINT GetBitCellDelta(const BYTE optimalBitTiming);
|
||||
UINT GetBitCellDelta(const ULONG uExecutedCycles);
|
||||
void UpdateBitStreamPosition(FloppyDisk& floppy, const ULONG bitCellDelta);
|
||||
void UpdateBitStreamOffsets(FloppyDisk& floppy);
|
||||
__forceinline void IncBitStream(FloppyDisk& floppy);
|
||||
void DataLatchReadWOZ(WORD pc, WORD addr, UINT bitCellRemainder);
|
||||
void DataLatchWriteWOZ(WORD pc, WORD addr, BYTE d, UINT bitCellRemainder);
|
||||
void DataLoadWriteWOZ(WORD pc, WORD addr, UINT bitCellRemainder);
|
||||
void DataShiftWriteWOZ(WORD pc, WORD addr, ULONG uExecutedCycles);
|
||||
void SetSequencerFunction(WORD addr);
|
||||
void DumpSectorWOZ(FloppyDisk floppy);
|
||||
void DumpTrackWOZ(FloppyDisk floppy);
|
||||
bool GetFirmware(LPCSTR lpName, BYTE* pDst);
|
||||
void InitFirmware(LPBYTE pCxRomPeripheral);
|
||||
|
||||
void SaveSnapshotFloppy(YamlSaveHelper& yamlSaveHelper, UINT unit);
|
||||
void SaveSnapshotDriveUnit(YamlSaveHelper& yamlSaveHelper, UINT unit);
|
||||
|
@ -206,7 +210,7 @@ private:
|
|||
void __stdcall ControlMotor(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles);
|
||||
void __stdcall Enable(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles);
|
||||
void __stdcall ReadWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
|
||||
void __stdcall DataLatchReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles);
|
||||
void __stdcall DataLatchReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, ULONG uExecutedCycles);
|
||||
void __stdcall LoadWriteProtect(WORD, WORD, BYTE write, BYTE value, ULONG);
|
||||
void __stdcall SetReadMode(WORD, WORD, BYTE, BYTE, ULONG);
|
||||
void __stdcall SetWriteMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles);
|
||||
|
@ -217,6 +221,11 @@ private:
|
|||
|
||||
//
|
||||
|
||||
static const UINT DISK2_FW_SIZE = 256;
|
||||
BYTE m_13SectorFirmware[DISK2_FW_SIZE];
|
||||
BYTE m_16SectorFirmware[DISK2_FW_SIZE];
|
||||
bool m_is13SectorFirmware;
|
||||
|
||||
WORD m_currDrive;
|
||||
FloppyDrive m_floppyDrive[NUM_DRIVES];
|
||||
BYTE m_floppyLatch;
|
||||
|
@ -240,8 +249,9 @@ private:
|
|||
BYTE m_shiftReg;
|
||||
int m_latchDelay;
|
||||
bool m_resetSequencer;
|
||||
bool m_writeStarted;
|
||||
|
||||
enum SEQFUNC {readSequencing=0, checkWriteProtAndInitWrite, dataShiftWrite, dataLoadWrite}; // UTAIIe 9-14
|
||||
enum SEQFUNC {readSequencing=0, dataShiftWrite, checkWriteProtAndInitWrite, dataLoadWrite}; // UTAIIe 9-14
|
||||
union SEQUENCER_FUNCTION
|
||||
{
|
||||
struct
|
||||
|
|
|
@ -118,3 +118,17 @@ void Disk2CardManager::Destroy(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Disk2CardManager::IsAnyFirmware13Sector(void)
|
||||
{
|
||||
for (UINT i = 0; i < NUM_SLOTS; i++)
|
||||
{
|
||||
if (g_CardMgr.QuerySlot(i) == CT_Disk2)
|
||||
{
|
||||
// If any Disk2 card has 13-sector firmware then return true
|
||||
if (dynamic_cast<Disk2InterfaceCard&>(g_CardMgr.GetRef(i)).GetCurrentFirmware() == 13)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -13,4 +13,5 @@ public:
|
|||
void SetEnhanceDisk(bool enhanceDisk);
|
||||
void LoadLastDiskImage(void);
|
||||
void Destroy(void);
|
||||
bool IsAnyFirmware13Sector(void);
|
||||
};
|
||||
|
|
|
@ -63,7 +63,7 @@ ImageError_e ImageOpen( const std::string & pszImageFilename,
|
|||
ImageError_e Err = pImageInfo->pImageHelper->Open(pszImageFilename.c_str(), pImageInfo, bCreateIfNecessary, strFilenameInZip);
|
||||
if (Err != eIMAGE_ERROR_NONE)
|
||||
{
|
||||
ImageClose(*ppImageInfo, true);
|
||||
ImageClose(*ppImageInfo);
|
||||
*ppImageInfo = NULL;
|
||||
return Err;
|
||||
}
|
||||
|
@ -83,9 +83,6 @@ ImageError_e ImageOpen( const std::string & pszImageFilename,
|
|||
|
||||
pImageInfo->uNumTracks = sg_DiskImageHelper.GetNumTracksInImage(pImageInfo->pImageType);
|
||||
|
||||
for (UINT uTrack = 0; uTrack < pImageInfo->uNumTracks; uTrack++)
|
||||
pImageInfo->ValidTrack[uTrack] = (pImageInfo->uImageSize > 0) ? 1 : 0;
|
||||
|
||||
*pWriteProtected = pImageInfo->bWriteProtected;
|
||||
|
||||
return eIMAGE_ERROR_NONE;
|
||||
|
@ -93,25 +90,9 @@ ImageError_e ImageOpen( const std::string & pszImageFilename,
|
|||
|
||||
//===========================================================================
|
||||
|
||||
void ImageClose(ImageInfo* const pImageInfo, const bool bOpenError /*=false*/)
|
||||
void ImageClose(ImageInfo* const pImageInfo)
|
||||
{
|
||||
bool bDeleteFile = false;
|
||||
|
||||
if (!bOpenError)
|
||||
{
|
||||
for (UINT uTrack = 0; uTrack < pImageInfo->uNumTracks; uTrack++)
|
||||
{
|
||||
if (!pImageInfo->ValidTrack[uTrack])
|
||||
{
|
||||
// TODO: Comment using info from this URL:
|
||||
// http://groups.google.de/group/comp.emulators.apple2/msg/7a1b9317e7905152
|
||||
bDeleteFile = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pImageInfo->pImageHelper->Close(pImageInfo, bDeleteFile);
|
||||
pImageInfo->pImageHelper->Close(pImageInfo);
|
||||
|
||||
delete pImageInfo;
|
||||
}
|
||||
|
@ -162,7 +143,7 @@ void ImageReadTrack( ImageInfo* const pImageInfo,
|
|||
|
||||
const UINT track = pImageInfo->pImageType->PhaseToTrack(phase);
|
||||
|
||||
if (pImageInfo->pImageType->AllowRW() && pImageInfo->ValidTrack[track])
|
||||
if (pImageInfo->pImageType->AllowRW())
|
||||
{
|
||||
pImageInfo->pImageType->Read(pImageInfo, phase, pTrackImageBuffer, pNibbles, pBitCount, enhanceDisk);
|
||||
}
|
||||
|
@ -190,7 +171,14 @@ void ImageWriteTrack( ImageInfo* const pImageInfo,
|
|||
if (pImageInfo->pImageType->AllowRW() && !pImageInfo->bWriteProtected)
|
||||
{
|
||||
pImageInfo->pImageType->Write(pImageInfo, phase, pTrackImageBuffer, nNibbles);
|
||||
pImageInfo->ValidTrack[track] = 1;
|
||||
|
||||
eImageType imageType = pImageInfo->pImageType->GetType();
|
||||
if (imageType == eImageWOZ1 || imageType == eImageWOZ2)
|
||||
{
|
||||
DWORD dummy;
|
||||
bool res = sg_DiskImageHelper.WOZUpdateInfo(pImageInfo, dummy);
|
||||
_ASSERT(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,7 +222,7 @@ bool ImageIsWriteProtected(ImageInfo* const pImageInfo)
|
|||
|
||||
bool ImageIsMultiFileZip(ImageInfo* const pImageInfo)
|
||||
{
|
||||
return pImageInfo ? (pImageInfo->uNumEntriesInZip > 1) : false;
|
||||
return pImageInfo ? (pImageInfo->uNumValidImagesInZip > 1) : false;
|
||||
}
|
||||
|
||||
const std::string & ImageGetPathname(ImageInfo* const pImageInfo)
|
||||
|
@ -258,6 +246,11 @@ BYTE ImageGetOptimalBitTiming(ImageInfo* const pImageInfo)
|
|||
return pImageInfo ? pImageInfo->optimalBitTiming : 32;
|
||||
}
|
||||
|
||||
bool ImageIsBootSectorFormatSector13(ImageInfo* const pImageInfo)
|
||||
{
|
||||
return pImageInfo ? pImageInfo->bootSectorFormat == CWOZHelper::bootSector13 : false;
|
||||
}
|
||||
|
||||
UINT ImagePhaseToTrack(ImageInfo* const pImageInfo, const float phase, const bool limit/*=true*/)
|
||||
{
|
||||
if (!pImageInfo)
|
||||
|
|
|
@ -51,7 +51,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
eIMAGE_ERROR_GZ,
|
||||
eIMAGE_ERROR_ZIP,
|
||||
eIMAGE_ERROR_REJECTED_MULTI_ZIP,
|
||||
eIMAGE_ERROR_UNSUPPORTED_MULTI_ZIP,
|
||||
eIMAGE_ERROR_UNABLE_TO_OPEN,
|
||||
eIMAGE_ERROR_UNABLE_TO_OPEN_GZ,
|
||||
eIMAGE_ERROR_UNABLE_TO_OPEN_ZIP,
|
||||
|
@ -66,7 +65,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
struct ImageInfo;
|
||||
|
||||
ImageError_e ImageOpen(const std::string & pszImageFilename, ImageInfo** ppImageInfo, bool* pWriteProtected, const bool bCreateIfNecessary, std::string& strFilenameInZip, const bool bExpectFloppy=true);
|
||||
void ImageClose(ImageInfo* const pImageInfo, const bool bOpenError=false);
|
||||
void ImageClose(ImageInfo* const pImageInfo);
|
||||
BOOL ImageBoot(ImageInfo* const pImageInfo);
|
||||
void ImageDestroy(void);
|
||||
void ImageInitialize(void);
|
||||
|
@ -85,5 +84,6 @@ bool ImageIsWOZ(ImageInfo* const pImageInfo);
|
|||
BYTE ImageGetOptimalBitTiming(ImageInfo* const pImageInfo);
|
||||
UINT ImagePhaseToTrack(ImageInfo* const pImageInfo, const float phase, const bool limit=true);
|
||||
UINT ImageGetMaxNibblesPerTrack(ImageInfo* const pImageInfo);
|
||||
bool ImageIsBootSectorFormatSector13(ImageInfo* const pImageInfo);
|
||||
|
||||
void GetImageTitle(LPCTSTR pPathname, std::string & pImageName, std::string & pFullName);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -31,12 +31,13 @@ struct ImageInfo
|
|||
std::string szFilenameInZip;
|
||||
zip_fileinfo zipFileInfo;
|
||||
UINT uNumEntriesInZip;
|
||||
UINT uNumValidImagesInZip;
|
||||
// Floppy only
|
||||
BYTE ValidTrack[TRACKS_MAX];
|
||||
UINT uNumTracks;
|
||||
BYTE* pImageBuffer;
|
||||
BYTE* pTrackMap; // WOZ only
|
||||
BYTE* pWOZTrackMap; // WOZ only (points into pImageBuffer)
|
||||
BYTE optimalBitTiming; // WOZ only
|
||||
BYTE bootSectorFormat; // WOZ only
|
||||
UINT maxNibblesPerTrack;
|
||||
|
||||
ImageInfo();
|
||||
|
@ -73,6 +74,7 @@ public:
|
|||
virtual const char* GetCreateExtensions(void) = 0;
|
||||
virtual const char* GetRejectExtensions(void) = 0;
|
||||
|
||||
bool WriteImageHeader(ImageInfo* pImageInfo, LPBYTE pHdr, const UINT hdrSize);
|
||||
void SetVolumeNumber(const BYTE uVolumeNumber) { m_uVolumeNumber = uVolumeNumber; }
|
||||
bool IsValidImageSize(const DWORD uImageSize);
|
||||
|
||||
|
@ -88,6 +90,7 @@ protected:
|
|||
bool WriteTrack(ImageInfo* pImageInfo, const int nTrack, LPBYTE pTrackBuffer, const UINT uTrackSize);
|
||||
bool ReadBlock(ImageInfo* pImageInfo, const int nBlock, LPBYTE pBlockBuffer);
|
||||
bool WriteBlock(ImageInfo* pImageInfo, const int nBlock, LPBYTE pBlockBuffer);
|
||||
bool WriteImageData(ImageInfo* pImageInfo, LPBYTE pSrcBuffer, const UINT uSrcSize, const long offset);
|
||||
|
||||
LPBYTE Code62(int sector);
|
||||
void Decode62(LPBYTE imageptr);
|
||||
|
@ -134,6 +137,10 @@ private:
|
|||
#pragma pack(push)
|
||||
#pragma pack(1) // Ensure Header2IMG & WOZ structs are packed
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200) // Allow zero-sized array in struct
|
||||
|
||||
|
||||
class C2IMGHelper : public CHdrHelper
|
||||
{
|
||||
public:
|
||||
|
@ -200,10 +207,16 @@ public:
|
|||
virtual ~CWOZHelper(void) {}
|
||||
virtual eDetectResult DetectHdr(LPBYTE& pImage, DWORD& dwImageSize, DWORD& dwOffset) { _ASSERT(0); return eMismatch; }
|
||||
virtual UINT GetMaxHdrSize(void) { return sizeof(WOZHeader); }
|
||||
eDetectResult ProcessChunks(const LPBYTE pImage, const DWORD dwImageSize, DWORD& dwOffset, BYTE*& pTrackMap);
|
||||
eDetectResult ProcessChunks(ImageInfo* pImageInfo, DWORD& dwOffset);
|
||||
bool IsWriteProtected(void) { return m_pInfo->v1.writeProtected == 1; }
|
||||
BYTE GetOptimalBitTiming(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->optimalBitTiming : CWOZHelper::InfoChunkv2::optimalBitTiming5_25; }
|
||||
UINT GetMaxNibblesPerTrack(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->largestTrack*CWOZHelper::BLOCK_SIZE : CWOZHelper::WOZ1_TRACK_SIZE; }
|
||||
BYTE GetOptimalBitTiming(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->optimalBitTiming : InfoChunkv2::optimalBitTiming5_25; }
|
||||
UINT GetMaxNibblesPerTrack(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->largestTrack*CWOZHelper::BLOCK_SIZE : WOZ1_TRACK_SIZE; }
|
||||
BYTE GetBootSectorFormat(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->bootSectorFormat : bootUnknown; }
|
||||
void InvalidateInfo(void) { m_pInfo = NULL; }
|
||||
BYTE* CreateEmptyDisk(DWORD& size);
|
||||
#if _DEBUG
|
||||
BYTE* CreateEmptyDiskv1(DWORD& size);
|
||||
#endif
|
||||
|
||||
static const UINT32 ID1_WOZ1 = '1ZOW'; // 'WOZ1'
|
||||
static const UINT32 ID1_WOZ2 = '2ZOW'; // 'WOZ2'
|
||||
|
@ -217,10 +230,29 @@ public:
|
|||
};
|
||||
|
||||
static const UINT32 MAX_TRACKS_5_25 = 40;
|
||||
static const UINT32 MAX_QUARTER_TRACKS_5_25 = MAX_TRACKS_5_25 * 4;
|
||||
static const UINT32 WOZ1_TRACK_SIZE = 6656; // 0x1A00
|
||||
static const UINT32 WOZ1_TRK_OFFSET = 6646;
|
||||
static const UINT32 EMPTY_TRACK_SIZE = 6400;
|
||||
static const UINT32 EMPTY_TRACK_SIZE = 6400; // $C.5 blocks
|
||||
static const UINT32 BLOCK_SIZE = 512;
|
||||
static const BYTE TMAP_TRACK_EMPTY = 0xFF;
|
||||
static const UINT16 TRK_DEFAULT_BLOCK_COUNT_5_25 = 13; // $D is default for TRKv2.blockCount
|
||||
|
||||
static const BYTE bootUnknown = 0;
|
||||
static const BYTE bootSector16 = 1;
|
||||
static const BYTE bootSector13 = 2;
|
||||
static const BYTE bootSectorBoth = 3;
|
||||
|
||||
struct WOZChunkHdr
|
||||
{
|
||||
UINT32 id;
|
||||
UINT32 size;
|
||||
};
|
||||
|
||||
struct Tmap
|
||||
{
|
||||
BYTE tmap[MAX_QUARTER_TRACKS_5_25];
|
||||
};
|
||||
|
||||
struct TRKv1
|
||||
{
|
||||
|
@ -239,17 +271,22 @@ public:
|
|||
UINT32 bitCount;
|
||||
};
|
||||
|
||||
struct Trks
|
||||
{
|
||||
TRKv2 trks[MAX_QUARTER_TRACKS_5_25];
|
||||
BYTE bits[0]; // bits[] starts at offset 3 x BLOCK_SIZE = 1536
|
||||
};
|
||||
|
||||
private:
|
||||
static const UINT32 INFO_CHUNK_ID = 'OFNI'; // 'INFO'
|
||||
static const UINT32 TMAP_CHUNK_ID = 'PAMT'; // 'TMAP'
|
||||
static const UINT32 TRKS_CHUNK_ID = 'SKRT'; // 'TRKS'
|
||||
static const UINT32 WRIT_CHUNK_ID = 'TIRW'; // 'WRIT' - WOZv2
|
||||
static const UINT32 META_CHUNK_ID = 'ATEM'; // 'META'
|
||||
static const UINT32 INFO_CHUNK_SIZE = 60; // Fixed size for both WOZv1 & WOZv2
|
||||
|
||||
struct InfoChunk
|
||||
{
|
||||
UINT32 id;
|
||||
UINT32 size;
|
||||
BYTE version;
|
||||
BYTE diskType;
|
||||
BYTE writeProtected; // 1 = Floppy is write protected
|
||||
|
@ -273,17 +310,44 @@ private:
|
|||
UINT16 requiredRAM; // in K (1024 bytes)
|
||||
UINT16 largestTrack; // in blocks (512 bytes)
|
||||
|
||||
static const BYTE bootUnknown = 0;
|
||||
static const BYTE bootSector16 = 1;
|
||||
static const BYTE bootSector13 = 2;
|
||||
static const BYTE bootSectorBoth = 3;
|
||||
|
||||
static const BYTE optimalBitTiming5_25 = 32;
|
||||
};
|
||||
|
||||
InfoChunkv2* m_pInfo;
|
||||
InfoChunkv2* m_pInfo; // NB. image-specific - only valid during Detect(), which calls InvalidateInfo() when done
|
||||
|
||||
//
|
||||
|
||||
struct WOZEmptyImage525 // 5.25"
|
||||
{
|
||||
WOZHeader hdr;
|
||||
|
||||
WOZChunkHdr infoHdr;
|
||||
InfoChunkv2 info;
|
||||
BYTE infoPadding[INFO_CHUNK_SIZE-sizeof(InfoChunkv2)];
|
||||
|
||||
WOZChunkHdr tmapHdr;
|
||||
Tmap tmap;
|
||||
|
||||
WOZChunkHdr trksHdr;
|
||||
Trks trks;
|
||||
};
|
||||
|
||||
struct WOZv1EmptyImage525 // 5.25"
|
||||
{
|
||||
WOZHeader hdr;
|
||||
|
||||
WOZChunkHdr infoHdr;
|
||||
InfoChunk info;
|
||||
BYTE infoPadding[INFO_CHUNK_SIZE-sizeof(InfoChunk)];
|
||||
|
||||
WOZChunkHdr tmapHdr;
|
||||
Tmap tmap;
|
||||
|
||||
WOZChunkHdr trksHdr;
|
||||
};
|
||||
};
|
||||
|
||||
#pragma warning(pop)
|
||||
#pragma pack(pop)
|
||||
|
||||
//-------------------------------------
|
||||
|
@ -304,7 +368,8 @@ public:
|
|||
}
|
||||
|
||||
ImageError_e Open(LPCTSTR pszImageFilename, ImageInfo* pImageInfo, const bool bCreateIfNecessary, std::string& strFilenameInZip);
|
||||
void Close(ImageInfo* pImageInfo, const bool bDeleteFile);
|
||||
void Close(ImageInfo* pImageInfo);
|
||||
bool WOZUpdateInfo(ImageInfo* pImageInfo, DWORD& dwOffset);
|
||||
|
||||
virtual CImageBase* Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, ImageInfo* pImageInfo) = 0;
|
||||
virtual CImageBase* GetImageForCreation(const TCHAR* pszExt, DWORD* pCreateImageSize) = 0;
|
||||
|
@ -317,7 +382,7 @@ protected:
|
|||
ImageError_e CheckNormalFile(LPCTSTR pszImageFilename, ImageInfo* pImageInfo, const bool bCreateIfNecessary);
|
||||
void GetCharLowerExt(TCHAR* pszExt, LPCTSTR pszImageFilename, const UINT uExtSize);
|
||||
void GetCharLowerExt2(TCHAR* pszExt, LPCTSTR pszImageFilename, const UINT uExtSize);
|
||||
void SetImageInfo(ImageInfo* pImageInfo, FileType_e eFileGZip, DWORD dwOffset, CImageBase* pImageType, DWORD dwSize);
|
||||
void SetImageInfo(ImageInfo* pImageInfo, FileType_e fileType, DWORD dwOffset, CImageBase* pImageType, DWORD dwSize);
|
||||
|
||||
UINT GetNumImages(void) { return m_vecImageTypes.size(); };
|
||||
CImageBase* GetImage(UINT uIndex) { _ASSERT(uIndex<GetNumImages()); return m_vecImageTypes[uIndex]; }
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#define LOG_DISK_NIBBLES_WRITE 1
|
||||
#define LOG_DISK_NIBBLES_WRITE_TRACK_GAPS 1 // Gap1, Gap2 & Gap3 info when writing a track
|
||||
#define LOG_DISK_NIBBLES_USE_RUNTIME_VAR 1
|
||||
#define LOG_DISK_WOZ_LOADWRITE 1
|
||||
#define LOG_DISK_WOZ_SHIFTWRITE 1
|
||||
|
||||
// __VA_ARGS__ not supported on MSVC++ .NET 7.x
|
||||
#if (LOG_DISK_ENABLED)
|
||||
|
|
|
@ -274,11 +274,12 @@ static void GetAppleWindowTitle()
|
|||
g_pAppTitle += " - ";
|
||||
|
||||
if( IsVideoStyle(VS_HALF_SCANLINES) )
|
||||
{
|
||||
g_pAppTitle += " 50% ";
|
||||
}
|
||||
g_pAppTitle += g_apVideoModeDesc[ g_eVideoType ];
|
||||
|
||||
if (g_CardMgr.GetDisk2CardMgr().IsAnyFirmware13Sector())
|
||||
g_pAppTitle += " (S6-13) ";
|
||||
|
||||
if (g_hCustomRomF8 != INVALID_HANDLE_VALUE)
|
||||
g_pAppTitle += TEXT(" (custom rom)");
|
||||
else if (sg_PropertySheet.GetTheFreezesF8Rom() && IS_APPLE2)
|
||||
|
@ -1420,7 +1421,6 @@ LRESULT CALLBACK FrameWndProc (
|
|||
LogOutput("WM_KEYDOWN: %08X (scanCode=%04X)\n", wparam, (lparam>>16)&0xfff);
|
||||
#endif
|
||||
if (!IsJoyKey &&
|
||||
!KeybGetAltStatus() && // GH#749 - AltGr also fakes CTRL being pressed!
|
||||
(g_nAppMode != MODE_LOGO)) // !MODE_LOGO - not emulating so don't pass to the VM's keyboard
|
||||
{
|
||||
// GH#678 Alternate key(s) to toggle max speed
|
||||
|
@ -1428,7 +1428,9 @@ LRESULT CALLBACK FrameWndProc (
|
|||
// . Ctrl-1: Speed = 1 MHz
|
||||
// . Ctrl-3: Speed = Full-Speed
|
||||
bool keyHandled = false;
|
||||
if( KeybGetCtrlStatus() && wparam >= '0' && wparam <= '9' )
|
||||
if( KeybGetCtrlStatus() &&
|
||||
!KeybGetAltStatus() && // GH#749 - AltGr also fakes CTRL being pressed!
|
||||
wparam >= '0' && wparam <= '9' )
|
||||
{
|
||||
switch (wparam)
|
||||
{
|
||||
|
|
|
@ -372,6 +372,11 @@ LanguageCardUnit* GetLanguageCard(void)
|
|||
return g_pLanguageCard;
|
||||
}
|
||||
|
||||
LPBYTE GetCxRomPeripheral(void)
|
||||
{
|
||||
return pCxRomPeripheral; // Can be NULL if at MODE_LOGO
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
static BYTE __stdcall IORead_C00x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles)
|
||||
|
|
|
@ -103,3 +103,5 @@ UINT GetRamWorksActiveBank(void);
|
|||
void SetSaturnMemorySize(UINT banks);
|
||||
void SetMemMainLanguageCard(LPBYTE ptr, bool bMemMain=false);
|
||||
class LanguageCardUnit* GetLanguageCard(void);
|
||||
|
||||
LPBYTE GetCxRomPeripheral(void);
|
||||
|
|
Loading…
Add table
Reference in a new issue