Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Andrea Odetti 2020-02-22 18:34:23 +00:00
commit 3b0043af6d
31 changed files with 970 additions and 584 deletions

View file

@ -1181,6 +1181,10 @@
RelativePath=".\resource\Disk2.rom"
>
</File>
<File
RelativePath=".\resource\Disk2-13sector.rom"
>
</File>
<File
RelativePath="RESOURCE\DISKOFF.BMP"
>

View file

@ -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.

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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 &lt;n&gt;<br>
Where n is [0..7]:
<ul>

View file

@ -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">

View file

@ -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>

View file

@ -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.&nbsp; 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".&nbsp; 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.&nbsp; If the extension is completely omitted,
".DSK" will be chosen by default.&nbsp; For more information, see <a href="ddi-formats.html">Disk Image Formats</a>.</p>
</body>

View file

@ -44,11 +44,22 @@ To do this, click the checkbox for "Open as Read Only" in the Select
Disk Image dialog.&nbsp; 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>&nbsp;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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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

Binary file not shown.

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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(),

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -13,4 +13,5 @@ public:
void SetEnhanceDisk(bool enhanceDisk);
void LoadLastDiskImage(void);
void Destroy(void);
bool IsAnyFirmware13Sector(void);
};

View file

@ -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)

View file

@ -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

View file

@ -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]; }

View file

@ -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)

View file

@ -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)
{

View file

@ -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)

View file

@ -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);