mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-12-23 00:30:17 +00:00
- Changed Disk_IORead and Disk_IOWrite and related functions to better reflect actual Disk II controller operation, mainly around reading & writing the latch
- Removed old disk stepping code as DataWiz confirmed he modified his Chessmaster 2000 crack to work on old AppleWin - this closes bug #18109 - https://groups.google.com/d/topic/comp.sys.apple2/xHrW45igYY8/discussion - Added a floppyloadmode variable for emulating $C08D (see UTA2E page 9-13) but commented out use of it as it's mostly implicit in this implementation - Tidied up logic in DiskReadWrite - Improved disk debug logging - Added TODO: ImageWriteTrack shouldn't take pFloppy->phase as a parameter
This commit is contained in:
parent
ed0e8925a4
commit
e37223feb0
238
source/Disk.cpp
238
source/Disk.cpp
@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows
|
|||||||
Copyright (C) 1994-1996, Michael O'Brien
|
Copyright (C) 1994-1996, Michael O'Brien
|
||||||
Copyright (C) 1999-2001, Oliver Schmidt
|
Copyright (C) 1999-2001, Oliver Schmidt
|
||||||
Copyright (C) 2002-2005, Tom Charlesworth
|
Copyright (C) 2002-2005, Tom Charlesworth
|
||||||
Copyright (C) 2006-2014, Tom Charlesworth, Michael Pohoreski
|
Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski, Nick Westgate
|
||||||
|
|
||||||
AppleWin is free software; you can redistribute it and/or modify
|
AppleWin is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -24,6 +24,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
/* Description: Disk
|
/* Description: Disk
|
||||||
*
|
*
|
||||||
* Author: Various
|
* Author: Various
|
||||||
|
*
|
||||||
|
* In comments, UTA2E is an abbreviation for a reference to "Understanding the Apple //e" by James Sather
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
@ -32,6 +34,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "Disk.h"
|
#include "Disk.h"
|
||||||
#include "DiskImage.h"
|
#include "DiskImage.h"
|
||||||
#include "Frame.h"
|
#include "Frame.h"
|
||||||
|
#include "Log.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
#include "Video.h"
|
#include "Video.h"
|
||||||
@ -108,6 +111,7 @@ static BOOL diskaccessed = 0;
|
|||||||
static Disk_t g_aFloppyDisk[NUM_DRIVES];
|
static Disk_t g_aFloppyDisk[NUM_DRIVES];
|
||||||
static BYTE floppylatch = 0;
|
static BYTE floppylatch = 0;
|
||||||
static BOOL floppymotoron = 0;
|
static BOOL floppymotoron = 0;
|
||||||
|
static BOOL floppyloadmode = 0; // for efficiency this is not used; it's extremely unlikely to affect emulation (nickw)
|
||||||
static BOOL floppywritemode = 0;
|
static BOOL floppywritemode = 0;
|
||||||
static WORD phases; // state bits for stepper magnet phases 0 - 3
|
static WORD phases; // state bits for stepper magnet phases 0 - 3
|
||||||
static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry
|
static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry
|
||||||
@ -152,13 +156,21 @@ char* DiskGetCurrentState(void)
|
|||||||
else if (floppywritemode)
|
else if (floppywritemode)
|
||||||
{
|
{
|
||||||
if (g_aFloppyDisk[currdrive].bWriteProtected)
|
if (g_aFloppyDisk[currdrive].bWriteProtected)
|
||||||
return "Writing";
|
|
||||||
else
|
|
||||||
return "Writing (write protected)";
|
return "Writing (write protected)";
|
||||||
|
else
|
||||||
|
return "Writing";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return "Reading";
|
/*if (floppyloadmode)
|
||||||
|
{
|
||||||
|
if (g_aFloppyDisk[currdrive].bWriteProtected)
|
||||||
|
return "Reading write protect state (write protected)";
|
||||||
|
else
|
||||||
|
return "Reading write protect state (not write protected)";
|
||||||
|
}
|
||||||
|
else*/
|
||||||
|
return "Reading";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +343,7 @@ static void ReadTrack(const int iDrive)
|
|||||||
|
|
||||||
if (pFloppy->trackimage && pFloppy->imagehandle)
|
if (pFloppy->trackimage && pFloppy->imagehandle)
|
||||||
{
|
{
|
||||||
LOG_DISK("read track %2X%s\r", pFloppy->track, (pFloppy->phase & 1) ? ".5" : "");
|
LOG_DISK("track $%02X%s read\r\n", pFloppy->track, (pFloppy->phase & 1) ? ".5" : " ");
|
||||||
|
|
||||||
ImageReadTrack(
|
ImageReadTrack(
|
||||||
pFloppy->imagehandle,
|
pFloppy->imagehandle,
|
||||||
@ -389,12 +401,16 @@ static void WriteTrack(const int iDrive)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (pFloppy->trackimage && pFloppy->imagehandle)
|
if (pFloppy->trackimage && pFloppy->imagehandle)
|
||||||
|
{
|
||||||
|
LOG_DISK("track $%02X%s write\r\n", pFloppy->track, (pFloppy->phase & 0) ? ".5" : " "); // TODO: hard-coded to whole tracks - see below (nickw)
|
||||||
|
|
||||||
ImageWriteTrack(
|
ImageWriteTrack(
|
||||||
pFloppy->imagehandle,
|
pFloppy->imagehandle,
|
||||||
pFloppy->track,
|
pFloppy->track,
|
||||||
pFloppy->phase,
|
pFloppy->phase, // TODO: this should never be used; it's the current phase (half-track), not that of the track to be written (nickw)
|
||||||
pFloppy->trackimage,
|
pFloppy->trackimage,
|
||||||
pFloppy->nibbles );
|
pFloppy->nibbles);
|
||||||
|
}
|
||||||
|
|
||||||
pFloppy->trackimagedirty = 0;
|
pFloppy->trackimagedirty = 0;
|
||||||
}
|
}
|
||||||
@ -415,34 +431,32 @@ void DiskBoot(void)
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskControlMotor(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskControlMotor(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
||||||
{
|
{
|
||||||
floppymotoron = address & 1;
|
floppymotoron = address & 1;
|
||||||
|
//LOG_DISK("motor %s\r\n", (floppymotoron) ? "on" : "off");
|
||||||
CheckSpinning();
|
CheckSpinning();
|
||||||
return MemReadFloatingBus(1, uExecutedCycles); // TC-TODO: Check b7 always set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
||||||
{
|
{
|
||||||
Disk_t * fptr = &g_aFloppyDisk[currdrive];
|
Disk_t * fptr = &g_aFloppyDisk[currdrive];
|
||||||
#if 1
|
int phase = (address >> 1) & 3;
|
||||||
int phase = (address >> 1) & 3;
|
|
||||||
int phase_bit = (1 << phase);
|
int phase_bit = (1 << phase);
|
||||||
|
|
||||||
|
#if 1
|
||||||
// update the magnet states
|
// update the magnet states
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
{
|
{
|
||||||
// phase on
|
// phase on
|
||||||
phases |= phase_bit;
|
phases |= phase_bit;
|
||||||
LOG_DISK("track %02X phases %X phase %d on address $C0E%X\r", fptr->phase, phases, phase, address & 0xF);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// phase off
|
// phase off
|
||||||
phases &= ~phase_bit;
|
phases &= ~phase_bit;
|
||||||
LOG_DISK("track %02X phases %X phase %d off address $C0E%X\r", fptr->phase, phases, phase, address & 0xF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for any stepping effect from a magnet
|
// check for any stepping effect from a magnet
|
||||||
@ -463,7 +477,6 @@ static BYTE __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG u
|
|||||||
const int nNumTracksInImage = ImageGetNumTracks(fptr->imagehandle);
|
const int nNumTracksInImage = ImageGetNumTracks(fptr->imagehandle);
|
||||||
const int newtrack = (nNumTracksInImage == 0) ? 0
|
const int newtrack = (nNumTracksInImage == 0) ? 0
|
||||||
: MIN(nNumTracksInImage-1, fptr->phase >> 1); // (round half tracks down)
|
: MIN(nNumTracksInImage-1, fptr->phase >> 1); // (round half tracks down)
|
||||||
LOG_DISK("newtrack %2X%s\r", newtrack, (fptr->phase & 1) ? ".5" : "");
|
|
||||||
if (newtrack != fptr->track)
|
if (newtrack != fptr->track)
|
||||||
{
|
{
|
||||||
if (fptr->trackimage && fptr->trackimagedirty)
|
if (fptr->trackimage && fptr->trackimagedirty)
|
||||||
@ -478,31 +491,21 @@ static BYTE __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG u
|
|||||||
// https://github.com/AppleWin/AppleWin/issues/201
|
// https://github.com/AppleWin/AppleWin/issues/201
|
||||||
FrameDrawDiskStatus( (HDC)0 );
|
FrameDrawDiskStatus( (HDC)0 );
|
||||||
}
|
}
|
||||||
#else // Old 1.13.1 code for Chessmaster 2000 to work! (see bug#18109)
|
#else
|
||||||
const int nNumTracksInImage = ImageGetNumTracks(fptr->imagehandle);
|
// substitute alternate stepping code here to test
|
||||||
if (address & 1) {
|
#endif
|
||||||
int phase = (address >> 1) & 3;
|
#if 0
|
||||||
int direction = 0;
|
LOG_DISK("track $%02X%s phases %d%d%d%d phase %d %s address $%4X\r\n",
|
||||||
if (phase == ((fptr->phase+1) & 3))
|
fptr->phase >> 1,
|
||||||
direction = 1;
|
(fptr->phase & 1) ? ".5" : " ",
|
||||||
if (phase == ((fptr->phase+3) & 3))
|
(phases >> 3) & 1,
|
||||||
direction = -1;
|
(phases >> 2) & 1,
|
||||||
if (direction) {
|
(phases >> 1) & 1,
|
||||||
fptr->phase = MAX(0,MIN(79,fptr->phase+direction));
|
(phases >> 0) & 1,
|
||||||
if (!(fptr->phase & 1)) {
|
phase,
|
||||||
int newtrack = MIN(nNumTracksInImage-1,fptr->phase >> 1);
|
(address & 1) ? "on " : "off",
|
||||||
if (newtrack != fptr->track) {
|
address);
|
||||||
if (fptr->trackimage && fptr->trackimagedirty)
|
|
||||||
WriteTrack(currdrive);
|
|
||||||
fptr->track = newtrack;
|
|
||||||
fptr->trackimagedata = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return ((address & 0xF) == 0) ? 0xFF // TC-TODO: Check why $C0E0 only returns 0xFF
|
|
||||||
: MemReadFloatingBus(1, uExecutedCycles); // TC-TODO: Check b7 always set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
@ -520,13 +523,12 @@ void DiskDestroy(void)
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskEnable(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskEnable(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles)
|
||||||
{
|
{
|
||||||
currdrive = address & 1;
|
currdrive = address & 1;
|
||||||
g_aFloppyDisk[!currdrive].spinning = 0;
|
g_aFloppyDisk[!currdrive].spinning = 0;
|
||||||
g_aFloppyDisk[!currdrive].writelight = 0;
|
g_aFloppyDisk[!currdrive].writelight = 0;
|
||||||
CheckSpinning();
|
CheckSpinning();
|
||||||
return MemReadFloatingBus(uExecutedCycles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
@ -793,8 +795,9 @@ bool Disk_IsDriveEmpty(const int iDrive)
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskReadWrite (WORD programcounter, WORD, BYTE, BYTE, ULONG)
|
static void __stdcall DiskReadWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
||||||
{
|
{
|
||||||
|
/* floppyloadmode = 0; */
|
||||||
Disk_t * fptr = &g_aFloppyDisk[currdrive];
|
Disk_t * fptr = &g_aFloppyDisk[currdrive];
|
||||||
|
|
||||||
diskaccessed = 1;
|
diskaccessed = 1;
|
||||||
@ -803,32 +806,23 @@ static BYTE __stdcall DiskReadWrite (WORD programcounter, WORD, BYTE, BYTE, ULON
|
|||||||
ReadTrack(currdrive);
|
ReadTrack(currdrive);
|
||||||
|
|
||||||
if (!fptr->trackimagedata)
|
if (!fptr->trackimagedata)
|
||||||
return 0xFF;
|
|
||||||
|
|
||||||
BYTE result = 0;
|
|
||||||
|
|
||||||
if (!floppywritemode || !fptr->bWriteProtected)
|
|
||||||
{
|
{
|
||||||
if (floppywritemode)
|
floppylatch = 0xFF;
|
||||||
{
|
return;
|
||||||
if (floppylatch & 0x80)
|
|
||||||
{
|
|
||||||
*(fptr->trackimage+fptr->byte) = floppylatch;
|
|
||||||
fptr->trackimagedirty = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = *(fptr->trackimage+fptr->byte);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0)
|
if (!floppywritemode)
|
||||||
{ LOG_DISK("nib %4X = %2X\r", fptr->byte, result); }
|
{
|
||||||
|
floppylatch = *(fptr->trackimage + fptr->byte);
|
||||||
|
#if 0
|
||||||
|
LOG_DISK("read %4X = %2X\r\n", fptr->byte, floppylatch);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if ((floppylatch & 0x80) && !fptr->bWriteProtected) // && floppywritemode
|
||||||
|
{
|
||||||
|
*(fptr->trackimage + fptr->byte) = floppylatch;
|
||||||
|
fptr->trackimagedirty = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (++fptr->byte >= fptr->nibbles)
|
if (++fptr->byte >= fptr->nibbles)
|
||||||
fptr->byte = 0;
|
fptr->byte = 0;
|
||||||
@ -838,8 +832,6 @@ static BYTE __stdcall DiskReadWrite (WORD programcounter, WORD, BYTE, BYTE, ULON
|
|||||||
// NB. Prevent flooding of forcing UI to redraw!!!
|
// NB. Prevent flooding of forcing UI to redraw!!!
|
||||||
if( ((fptr->byte) & 0xFF) == 0 )
|
if( ((fptr->byte) & 0xFF) == 0 )
|
||||||
FrameDrawDiskStatus( (HDC)0 );
|
FrameDrawDiskStatus( (HDC)0 );
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
@ -909,24 +901,31 @@ void DiskSelect(const int iDrive)
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskSetLatchValue(WORD, WORD, BYTE write, BYTE value, ULONG)
|
static void __stdcall DiskLoadWriteProtect(WORD, WORD, BYTE write, BYTE value, ULONG) {
|
||||||
{
|
/* floppyloadmode = 1; */
|
||||||
if (write)
|
if (!write)
|
||||||
floppylatch = value;
|
{
|
||||||
return floppylatch;
|
if (floppymotoron && !floppywritemode)
|
||||||
|
{
|
||||||
|
// phase 1 on also forces write protect in the Disk II drive (UTA2E page 9-7) but we don't implement that
|
||||||
|
if (g_aFloppyDisk[currdrive].bWriteProtected)
|
||||||
|
floppylatch |= 0x80;
|
||||||
|
else
|
||||||
|
floppylatch &= 0x7F;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskSetReadMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskSetReadMode(WORD, WORD, BYTE, BYTE, ULONG)
|
||||||
{
|
{
|
||||||
floppywritemode = 0;
|
floppywritemode = 0;
|
||||||
return MemReadFloatingBus(g_aFloppyDisk[currdrive].bWriteProtected, uExecutedCycles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static BYTE __stdcall DiskSetWriteMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles)
|
static void __stdcall DiskSetWriteMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles)
|
||||||
{
|
{
|
||||||
floppywritemode = 1;
|
floppywritemode = 1;
|
||||||
BOOL modechange = !g_aFloppyDisk[currdrive].writelight;
|
BOOL modechange = !g_aFloppyDisk[currdrive].writelight;
|
||||||
@ -936,8 +935,6 @@ static BYTE __stdcall DiskSetWriteMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCy
|
|||||||
//FrameRefreshStatus(DRAW_LEDS);
|
//FrameRefreshStatus(DRAW_LEDS);
|
||||||
FrameDrawDiskLEDS( (HDC)0 );
|
FrameDrawDiskLEDS( (HDC)0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return MemReadFloatingBus(1, uExecutedCycles); // TC-TODO: Check b7 always set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
@ -1032,12 +1029,12 @@ void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot)
|
|||||||
|
|
||||||
memcpy(pCxRomPeripheral + uSlot*APPLE_SLOT_SIZE, pData, DISK2_FW_SIZE);
|
memcpy(pCxRomPeripheral + uSlot*APPLE_SLOT_SIZE, pData, DISK2_FW_SIZE);
|
||||||
|
|
||||||
// NB. We used to disable the track stepping delay in the Disk II controller firmware by
|
// Note: We used to disable the track stepping delay in the Disk II controller firmware by
|
||||||
// patching $C64C with $A9,$00,$EA. Now not doing this since:
|
// patching $C64C with $A9,$00,$EA. Now not doing this since:
|
||||||
// . Authentic Speed should be authentic
|
// . Authentic Speed should be authentic
|
||||||
// . Enhanced Speed runs emulation unthrottled, so removing the delay has negligible effect
|
// . Enhanced Speed runs emulation unthrottled, so removing the delay has negligible effect
|
||||||
// . Patching the firmware breaks the ADC checksum used by "The CIA Files" (Tricky Dick)
|
// . Patching the firmware breaks the ADC checksum used by "The CIA Files" (Tricky Dick)
|
||||||
// . In this case we can patch to compensate for an ADC or EOR checksum but not both
|
// . In this case we can patch to compensate for an ADC or EOR checksum but not both (nickw)
|
||||||
|
|
||||||
RegisterIoHandler(uSlot, Disk_IORead, Disk_IOWrite, NULL, NULL, NULL, NULL);
|
RegisterIoHandler(uSlot, Disk_IORead, Disk_IOWrite, NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
@ -1046,55 +1043,60 @@ void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot)
|
|||||||
|
|
||||||
static BYTE __stdcall Disk_IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
static BYTE __stdcall Disk_IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
||||||
{
|
{
|
||||||
addr &= 0xFF;
|
switch (addr & 0xF)
|
||||||
|
|
||||||
switch (addr & 0xf)
|
|
||||||
{
|
{
|
||||||
case 0x0: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x0: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x1: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x1: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x2: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x2: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x3: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x3: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x4: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x4: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x5: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x5: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x6: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x6: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x7: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x7: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x8: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x8: DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x9: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x9: DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xA: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xA: DiskEnable(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xB: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xB: DiskEnable(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xC: return DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xC: DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xD: return DiskSetLatchValue(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xD: DiskLoadWriteProtect(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xE: return DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xE: DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xF: return DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xF: DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
// only even addresses return the latch (UTA2E Table 9.1)
|
||||||
|
if (!(addr & 1))
|
||||||
|
return floppylatch;
|
||||||
|
else
|
||||||
|
return MemReadFloatingBus(nCyclesLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BYTE __stdcall Disk_IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
static BYTE __stdcall Disk_IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft)
|
||||||
{
|
{
|
||||||
addr &= 0xFF;
|
switch (addr & 0xF)
|
||||||
|
|
||||||
switch (addr & 0xf)
|
|
||||||
{
|
{
|
||||||
case 0x0: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x0: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x1: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x1: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x2: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x2: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x3: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x3: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x4: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x4: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x5: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x5: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x6: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x6: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x7: return DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x7: DiskControlStepper(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x8: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x8: DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0x9: return DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft);
|
case 0x9: DiskControlMotor(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xA: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xA: DiskEnable(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xB: return DiskEnable(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xB: DiskEnable(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xC: return DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xC: DiskReadWrite(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xD: return DiskSetLatchValue(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xD: DiskLoadWriteProtect(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xE: return DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xE: DiskSetReadMode(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
case 0xF: return DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft);
|
case 0xF: DiskSetWriteMode(pc, addr, bWrite, d, nCyclesLeft); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// any address writes the latch via sequencer LD command (74LS323 datasheet)
|
||||||
|
if (floppywritemode /* && floppyloadmode */)
|
||||||
|
{
|
||||||
|
floppylatch = d;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user