Added support for keyboard shift key down as game port button 2 [TN9].
Refactored memory to use peripheral cards; added place holder for NoSlotClock. --HG-- extra : convert_revision : svn%3Affd33b8c-2492-42e0-bdc5-587b920b7d6d/trunk%4050808
This commit is contained in:
parent
5485e01e02
commit
ee4c69dddf
|
@ -2,7 +2,7 @@
|
|||
<Dictionary>
|
||||
<Acronyms>
|
||||
<CasingExceptions>
|
||||
<Acronym>CXXX</Acronym>
|
||||
<Acronym>Io</Acronym>
|
||||
<Acronym>RPC</Acronym>
|
||||
</CasingExceptions>
|
||||
</Acronyms>
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Jellyfish.Library;
|
||||
using Jellyfish.Virtu.Services;
|
||||
using Jellyfish.Virtu.Settings;
|
||||
|
||||
namespace Jellyfish.Virtu
|
||||
{
|
||||
public sealed class DiskIIController : PeripheralCard
|
||||
{
|
||||
public DiskIIController(Machine machine) :
|
||||
base(machine)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
var romStream = StorageService.GetResourceStream("Roms/DiskII.rom", 0x0100);
|
||||
romStream.ReadBlock(_romRegionC1C7, 0x0000, 0x0100);
|
||||
|
||||
_drives[0].InsertDisk("Default.dsk", StorageService.GetResourceStream("Disks/Default.dsk", 0x23000), false);
|
||||
#if WINDOWS
|
||||
var settings = Machine.Settings.DiskII;
|
||||
if (settings.Disk1.Name.Length > 0)
|
||||
{
|
||||
_drives[0].InsertDisk(settings.Disk1.Name, settings.Disk1.IsWriteProtected);
|
||||
}
|
||||
if (settings.Disk2.Name.Length > 0)
|
||||
{
|
||||
_drives[1].InsertDisk(settings.Disk2.Name, settings.Disk2.IsWriteProtected);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_phaseStates = 0;
|
||||
SetMotorOn(false);
|
||||
SetDriveNumber(0);
|
||||
_loadMode = false;
|
||||
_writeMode = false;
|
||||
}
|
||||
|
||||
public override void Uninitialize()
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
public override int ReadIoRegionC0C0(int address)
|
||||
{
|
||||
switch (address & 0xF)
|
||||
{
|
||||
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
|
||||
SetPhase(address);
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
SetMotorOn(false);
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
SetMotorOn(true);
|
||||
break;
|
||||
|
||||
case 0xA:
|
||||
SetDriveNumber(0);
|
||||
break;
|
||||
|
||||
case 0xB:
|
||||
SetDriveNumber(1);
|
||||
break;
|
||||
|
||||
case 0xC:
|
||||
_loadMode = false;
|
||||
if (_motorOn)
|
||||
{
|
||||
if (!_writeMode)
|
||||
{
|
||||
return _latch = _drives[_driveNumber].Read();
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLatch();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xD:
|
||||
_loadMode = true;
|
||||
if (_motorOn && !_writeMode)
|
||||
{
|
||||
// write protect is forced if phase 1 is on [F9.7]
|
||||
_latch &= 0x7F;
|
||||
if (_drives[_driveNumber].IsWriteProtected ||
|
||||
(_phaseStates & Phase1On) != 0)
|
||||
{
|
||||
_latch |= 0x80;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE:
|
||||
_writeMode = false;
|
||||
break;
|
||||
|
||||
case 0xF:
|
||||
_writeMode = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((address & 1) == 0)
|
||||
{
|
||||
// only even addresses return the latch
|
||||
if (_motorOn)
|
||||
{
|
||||
return _latch;
|
||||
}
|
||||
|
||||
// simple hack to fool DOS SAMESLOT drive spin check (usually at $BD34)
|
||||
_driveSpin = !_driveSpin;
|
||||
return _driveSpin ? 0x7E : 0x7F;
|
||||
}
|
||||
|
||||
return ReadFloatingBus();
|
||||
}
|
||||
|
||||
public override int ReadIoRegionC1C7(int address)
|
||||
{
|
||||
return _romRegionC1C7[address & 0xFF];
|
||||
}
|
||||
|
||||
public override void WriteIoRegionC0C0(int address, int data)
|
||||
{
|
||||
switch (address & 0xF)
|
||||
{
|
||||
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
|
||||
SetPhase(address);
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
SetMotorOn(false);
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
SetMotorOn(true);
|
||||
break;
|
||||
|
||||
case 0xA:
|
||||
SetDriveNumber(0);
|
||||
break;
|
||||
|
||||
case 0xB:
|
||||
SetDriveNumber(1);
|
||||
break;
|
||||
|
||||
case 0xC:
|
||||
_loadMode = false;
|
||||
if (_writeMode)
|
||||
{
|
||||
WriteLatch();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xD:
|
||||
_loadMode = true;
|
||||
break;
|
||||
|
||||
case 0xE:
|
||||
_writeMode = false;
|
||||
break;
|
||||
|
||||
case 0xF:
|
||||
_writeMode = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_motorOn && _writeMode)
|
||||
{
|
||||
if (_loadMode)
|
||||
{
|
||||
// any address writes latch for sequencer LD; OE1/2 irrelevant ['323 datasheet]
|
||||
_latch = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteLatch()
|
||||
{
|
||||
// write protect is forced if phase 1 is on [F9.7]
|
||||
if ((_phaseStates & Phase1On) == 0)
|
||||
{
|
||||
_drives[_driveNumber].Write(_latch);
|
||||
}
|
||||
}
|
||||
|
||||
private void Flush()
|
||||
{
|
||||
_drives[_driveNumber].FlushTrack();
|
||||
}
|
||||
|
||||
private void SetDriveNumber(int driveNumber)
|
||||
{
|
||||
if (_driveNumber != driveNumber)
|
||||
{
|
||||
Flush();
|
||||
_driveNumber = driveNumber;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetMotorOn(bool state)
|
||||
{
|
||||
if (_motorOn && !state)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
_motorOn = state;
|
||||
}
|
||||
|
||||
private void SetPhase(int address)
|
||||
{
|
||||
int phase = (address >> 1) & 0x3;
|
||||
int state = address & 1;
|
||||
_phaseStates &= ~(1 << phase);
|
||||
_phaseStates |= (state << phase);
|
||||
|
||||
if (_motorOn)
|
||||
{
|
||||
_drives[_driveNumber].ApplyPhaseChange(_phaseStates);
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
||||
public DiskIIDrive[] Drives { get { return _drives; } }
|
||||
|
||||
private const int Phase0On = 1 << 0;
|
||||
private const int Phase1On = 1 << 1;
|
||||
private const int Phase2On = 1 << 2;
|
||||
private const int Phase3On = 1 << 3;
|
||||
|
||||
private DiskIIDrive[] _drives = new DiskIIDrive[] { new DiskIIDrive(), new DiskIIDrive() };
|
||||
private int _latch;
|
||||
private int _phaseStates;
|
||||
private bool _motorOn;
|
||||
private int _driveNumber;
|
||||
private bool _loadMode;
|
||||
private bool _writeMode;
|
||||
private bool _driveSpin;
|
||||
|
||||
private byte[] _romRegionC1C7 = new byte[0x0100];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using Jellyfish.Library;
|
||||
|
||||
namespace Jellyfish.Virtu
|
||||
{
|
||||
public sealed class DiskIIDrive
|
||||
{
|
||||
public DiskIIDrive()
|
||||
{
|
||||
DriveArmStepDelta[0] = new int[] { 0, 0, 1, 1, 0, 0, 1, 1, -1, -1, 0, 0, -1, -1, 0, 0 }; // phase 0
|
||||
DriveArmStepDelta[1] = new int[] { 0, -1, 0, -1, 1, 0, 1, 0, 0, -1, 0, -1, 1, 0, 1, 0 }; // phase 1
|
||||
DriveArmStepDelta[2] = new int[] { 0, 0, -1, -1, 0, 0, -1, -1, 1, 1, 0, 0, 1, 1, 0, 0 }; // phase 2
|
||||
DriveArmStepDelta[3] = new int[] { 0, 1, 0, 1, -1, 0, -1, 0, 0, 1, 0, 1, -1, 0, -1, 0 }; // phase 3
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
public void InsertDisk(string fileName, bool isWriteProtected)
|
||||
{
|
||||
using (var stream = File.OpenRead(fileName))
|
||||
{
|
||||
InsertDisk(fileName, stream, isWriteProtected);
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertDisk(string name, Stream stream, bool isWriteProtected)
|
||||
{
|
||||
FlushTrack();
|
||||
|
||||
// TODO handle null param/empty string for eject, or add Eject()
|
||||
|
||||
_disk = Disk525.CreateDisk(name, stream.ReadAllBytes(), isWriteProtected);
|
||||
_trackLoaded = false;
|
||||
}
|
||||
|
||||
public void ApplyPhaseChange(int phaseState)
|
||||
{
|
||||
// step the drive head according to stepper magnet changes
|
||||
int delta = DriveArmStepDelta[_trackNumber & 0x3][phaseState];
|
||||
if (delta != 0)
|
||||
{
|
||||
int newTrackNumber = MathHelpers.Clamp(_trackNumber + delta, 0, TrackNumberMax);
|
||||
if (newTrackNumber != _trackNumber)
|
||||
{
|
||||
FlushTrack();
|
||||
_trackNumber = newTrackNumber;
|
||||
_trackOffset = 0;
|
||||
_trackLoaded = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Read()
|
||||
{
|
||||
if (LoadTrack())
|
||||
{
|
||||
int data = _trackData[_trackOffset++];
|
||||
if (_trackOffset >= Disk525.TrackSize)
|
||||
{
|
||||
_trackOffset = 0;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return _random.Next(0x01, 0xFF);
|
||||
}
|
||||
|
||||
public void Write(int data)
|
||||
{
|
||||
if (LoadTrack())
|
||||
{
|
||||
_trackChanged = true;
|
||||
_trackData[_trackOffset++] = (byte)data;
|
||||
if (_trackOffset >= Disk525.TrackSize)
|
||||
{
|
||||
_trackOffset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool LoadTrack()
|
||||
{
|
||||
if (!_trackLoaded && (_disk != null))
|
||||
{
|
||||
_disk.ReadTrack(_trackNumber, 0, _trackData);
|
||||
_trackLoaded = true;
|
||||
}
|
||||
|
||||
return _trackLoaded;
|
||||
}
|
||||
|
||||
public void FlushTrack()
|
||||
{
|
||||
if (_trackChanged)
|
||||
{
|
||||
_disk.WriteTrack(_trackNumber, 0, _trackData);
|
||||
_trackChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsWriteProtected { get { return _disk.IsWriteProtected; } }
|
||||
|
||||
private const int TrackNumberMax = 0x44;
|
||||
|
||||
private const int PhaseCount = 4;
|
||||
|
||||
private readonly int[][] DriveArmStepDelta = new int[PhaseCount][];
|
||||
|
||||
private Disk525 _disk;
|
||||
private bool _trackLoaded;
|
||||
private bool _trackChanged;
|
||||
private int _trackNumber;
|
||||
private int _trackOffset;
|
||||
private byte[] _trackData = new byte[Disk525.TrackSize];
|
||||
|
||||
private Random _random = new Random();
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ namespace Jellyfish.Virtu
|
|||
{
|
||||
var settings = Machine.Settings.GamePort;
|
||||
|
||||
return (_gamePortService.IsButton2Down ||
|
||||
return (_gamePortService.IsButton2Down || _keyboardService.IsShiftKeyDown || // [TN9]
|
||||
(settings.UseKeyboard && (settings.Key.Button2 > 0) && _keyboardService.IsKeyDown(settings.Key.Button2)));
|
||||
}
|
||||
|
||||
|
|
|
@ -19,13 +19,24 @@ namespace Jellyfish.Virtu
|
|||
|
||||
Cpu = new Cpu(this);
|
||||
Memory = new Memory(this);
|
||||
DiskII = new DiskII(this);
|
||||
Keyboard = new Keyboard(this);
|
||||
GamePort = new GamePort(this);
|
||||
Cassette = new Cassette(this);
|
||||
Speaker = new Speaker(this);
|
||||
Video = new Video(this);
|
||||
Components = new Collection<MachineComponent> { Cpu, Memory, DiskII, Keyboard, GamePort, Cassette, Speaker, Video };
|
||||
NoSlotClock = new NoSlotClock();
|
||||
|
||||
var emptySlot = new PeripheralCard(this);
|
||||
Slot1 = emptySlot;
|
||||
Slot2 = emptySlot;
|
||||
Slot3 = emptySlot;
|
||||
Slot4 = emptySlot;
|
||||
Slot5 = emptySlot;
|
||||
Slot6 = new DiskIIController(this);
|
||||
Slot7 = emptySlot;
|
||||
|
||||
Slots = new Collection<PeripheralCard> { null, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
|
||||
Components = new Collection<MachineComponent> { Cpu, Memory, Keyboard, GamePort, Cassette, Speaker, Video, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
|
||||
|
||||
Thread = new Thread(Run) { Name = "Machine" };
|
||||
}
|
||||
|
@ -76,6 +87,20 @@ namespace Jellyfish.Virtu
|
|||
}
|
||||
}
|
||||
|
||||
public DiskIIController FindDiskIIController()
|
||||
{
|
||||
for (int i = 7; i >= 1; i--)
|
||||
{
|
||||
var diskII = Slots[i] as DiskIIController;
|
||||
if (diskII != null)
|
||||
{
|
||||
return diskII;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void Run() // machine thread
|
||||
{
|
||||
Components.ForEach(component => component.Initialize());
|
||||
|
@ -108,12 +133,22 @@ namespace Jellyfish.Virtu
|
|||
|
||||
public Cpu Cpu { get; private set; }
|
||||
public Memory Memory { get; private set; }
|
||||
public DiskII DiskII { get; private set; }
|
||||
public Keyboard Keyboard { get; private set; }
|
||||
public GamePort GamePort { get; private set; }
|
||||
public Cassette Cassette { get; private set; }
|
||||
public Speaker Speaker { get; private set; }
|
||||
public Video Video { get; private set; }
|
||||
public NoSlotClock NoSlotClock { get; private set; }
|
||||
|
||||
public PeripheralCard Slot1 { get; private set; }
|
||||
public PeripheralCard Slot2 { get; private set; }
|
||||
public PeripheralCard Slot3 { get; private set; }
|
||||
public PeripheralCard Slot4 { get; private set; }
|
||||
public PeripheralCard Slot5 { get; private set; }
|
||||
public PeripheralCard Slot6 { get; private set; }
|
||||
public PeripheralCard Slot7 { get; private set; }
|
||||
|
||||
public Collection<PeripheralCard> Slots { get; private set; }
|
||||
public Collection<MachineComponent> Components { get; private set; }
|
||||
|
||||
public Thread Thread { get; private set; }
|
||||
|
|
173
Virtu/Memory.cs
173
Virtu/Memory.cs
|
@ -81,12 +81,12 @@ namespace Jellyfish.Virtu
|
|||
|
||||
public override void Initialize()
|
||||
{
|
||||
_diskII = Machine.DiskII;
|
||||
_keyboard = Machine.Keyboard;
|
||||
_gamePort = Machine.GamePort;
|
||||
_cassette = Machine.Cassette;
|
||||
_speaker = Machine.Speaker;
|
||||
_video = Machine.Video;
|
||||
_noSlotClock = Machine.NoSlotClock;
|
||||
|
||||
var romStream = StorageService.GetResourceStream("Roms/AppleIIe.rom", 0x4000);
|
||||
romStream.Seek(0x0100, SeekOrigin.Current);
|
||||
|
@ -94,9 +94,6 @@ namespace Jellyfish.Virtu
|
|||
romStream.ReadBlock(_romRegionD0DF, 0x0000, 0x1000);
|
||||
romStream.ReadBlock(_romRegionE0FF, 0x0000, 0x2000);
|
||||
|
||||
romStream = StorageService.GetResourceStream("Roms/DiskII.rom", 0x0100);
|
||||
romStream.ReadBlock(_romExternalRegionC1CF, 0x0500, 0x0100);
|
||||
|
||||
if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0xC1))
|
||||
{
|
||||
Monitor = MonitorType.Standard;
|
||||
|
@ -105,14 +102,12 @@ namespace Jellyfish.Virtu
|
|||
{
|
||||
Monitor = MonitorType.Enhanced;
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(_romInternalRegionC1CF, 0x0700, _romExternalRegionC1CF, 0x0700, 0x0800);
|
||||
}
|
||||
|
||||
public override void Reset() // [7-3]
|
||||
{
|
||||
ResetState(State80Col | State80Store | StateAltChrSet | StateAltZP | StateBank1 | StateHRamRd | StateHRamPreWrt | StateHRamWrt | // HRamWrt' [5-23]
|
||||
StateHires | StatePage2 | StateRamRd | StateRamWrt | StateSlotC3Rom | StateIntCXRom | StateAn0 | StateAn1 | StateAn2 | StateAn3);
|
||||
StateHires | StatePage2 | StateRamRd | StateRamWrt | StateIntCXRom | StateSlotC3Rom | StateIntC8Rom | StateAn0 | StateAn1 | StateAn2 | StateAn3);
|
||||
SetState(StateDRes); // An3' -> DRes [8-20]
|
||||
|
||||
MapRegion0001();
|
||||
|
@ -125,8 +120,7 @@ namespace Jellyfish.Virtu
|
|||
public int Read(int address)
|
||||
{
|
||||
int region = PageRegion[address >> 8];
|
||||
|
||||
return (region == RegionC0C0) ? ReadIoC0XX(address) : _regionRead[region][address - RegionBaseAddress[region]];
|
||||
return ((address & 0xF000) != 0xC000) ? _regionRead[region][address - RegionBaseAddress[region]] : ReadIoRegionC0CF(address);
|
||||
}
|
||||
|
||||
public int ReadZeroPage(int address)
|
||||
|
@ -154,9 +148,29 @@ namespace Jellyfish.Virtu
|
|||
#endregion
|
||||
|
||||
#region Read Actions
|
||||
private int ReadIoRegionC0CF(int address)
|
||||
{
|
||||
switch (address & 0xFF00)
|
||||
{
|
||||
case 0xC000:
|
||||
return ReadIoRegionC0C0(address);
|
||||
|
||||
case 0xC100: case 0xC200: case 0xC400: case 0xC500: case 0xC600: case 0xC700:
|
||||
return ReadIoRegionC1C7(address);
|
||||
|
||||
case 0xC300:
|
||||
return ReadIoRegionC3C3(address);
|
||||
|
||||
case 0xC800: case 0xC900: case 0xCA00: case 0xCB00: case 0xCC00: case 0xCD00: case 0xCE00: case 0xCF00:
|
||||
return ReadIoRegionC8CF(address);
|
||||
}
|
||||
|
||||
return _video.ReadFloatingBus();
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
||||
private int ReadIoC0XX(int address)
|
||||
private int ReadIoRegionC0C0(int address)
|
||||
{
|
||||
switch (address)
|
||||
{
|
||||
|
@ -181,13 +195,13 @@ namespace Jellyfish.Virtu
|
|||
return SetBit7(_keyboard.ReadLatch(), IsRamWriteAux);
|
||||
|
||||
case 0xC015:
|
||||
return SetBit7(_keyboard.ReadLatch(), IsRomCXXXInternal);
|
||||
return SetBit7(_keyboard.ReadLatch(), IsRomC1CFInternal);
|
||||
|
||||
case 0xC016:
|
||||
return SetBit7(_keyboard.ReadLatch(), IsZeroPageAux);
|
||||
|
||||
case 0xC017:
|
||||
return SetBit7(_keyboard.ReadLatch(), IsRomC3XXExternal);
|
||||
return SetBit7(_keyboard.ReadLatch(), IsRomC3C3External);
|
||||
|
||||
case 0xC018:
|
||||
return SetBit7(_keyboard.ReadLatch(), Is80Store);
|
||||
|
@ -296,37 +310,62 @@ namespace Jellyfish.Virtu
|
|||
|
||||
case 0xC090: case 0xC091: case 0xC092: case 0xC093: case 0xC094: case 0xC095: case 0xC096: case 0xC097: // slot1
|
||||
case 0xC098: case 0xC099: case 0xC09A: case 0xC09B: case 0xC09C: case 0xC09D: case 0xC09E: case 0xC09F:
|
||||
break;
|
||||
return Machine.Slot1.ReadIoRegionC0C0(address);
|
||||
|
||||
case 0xC0A0: case 0xC0A1: case 0xC0A2: case 0xC0A3: case 0xC0A4: case 0xC0A5: case 0xC0A6: case 0xC0A7: // slot2
|
||||
case 0xC0A8: case 0xC0A9: case 0xC0AA: case 0xC0AB: case 0xC0AC: case 0xC0AD: case 0xC0AE: case 0xC0AF:
|
||||
break;
|
||||
return Machine.Slot2.ReadIoRegionC0C0(address);
|
||||
|
||||
case 0xC0B0: case 0xC0B1: case 0xC0B2: case 0xC0B3: case 0xC0B4: case 0xC0B5: case 0xC0B6: case 0xC0B7: // slot3
|
||||
case 0xC0B8: case 0xC0B9: case 0xC0BA: case 0xC0BB: case 0xC0BC: case 0xC0BD: case 0xC0BE: case 0xC0BF:
|
||||
break;
|
||||
return Machine.Slot3.ReadIoRegionC0C0(address);
|
||||
|
||||
case 0xC0C0: case 0xC0C1: case 0xC0C2: case 0xC0C3: case 0xC0C4: case 0xC0C5: case 0xC0C6: case 0xC0C7: // slot4
|
||||
case 0xC0C8: case 0xC0C9: case 0xC0CA: case 0xC0CB: case 0xC0CC: case 0xC0CD: case 0xC0CE: case 0xC0CF:
|
||||
break;
|
||||
return Machine.Slot4.ReadIoRegionC0C0(address);
|
||||
|
||||
case 0xC0D0: case 0xC0D1: case 0xC0D2: case 0xC0D3: case 0xC0D4: case 0xC0D5: case 0xC0D6: case 0xC0D7: // slot5
|
||||
case 0xC0D8: case 0xC0D9: case 0xC0DA: case 0xC0DB: case 0xC0DC: case 0xC0DD: case 0xC0DE: case 0xC0DF:
|
||||
break;
|
||||
return Machine.Slot5.ReadIoRegionC0C0(address);
|
||||
|
||||
case 0xC0E0: case 0xC0E1: case 0xC0E2: case 0xC0E3: case 0xC0E4: case 0xC0E5: case 0xC0E6: case 0xC0E7: // slot6
|
||||
case 0xC0E8: case 0xC0E9: case 0xC0EA: case 0xC0EB: case 0xC0EC: case 0xC0ED: case 0xC0EE: case 0xC0EF:
|
||||
return _diskII.Read(address);
|
||||
return Machine.Slot6.ReadIoRegionC0C0(address);
|
||||
|
||||
case 0xC0F0: case 0xC0F1: case 0xC0F2: case 0xC0F3: case 0xC0F4: case 0xC0F5: case 0xC0F6: case 0xC0F7: // slot7
|
||||
case 0xC0F8: case 0xC0F9: case 0xC0FA: case 0xC0FB: case 0xC0FC: case 0xC0FD: case 0xC0FE: case 0xC0FF:
|
||||
break;
|
||||
return Machine.Slot7.ReadIoRegionC0C0(address);
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("address");
|
||||
}
|
||||
|
||||
return _video.ReadFloatingBus(); // [5-40]
|
||||
return _video.ReadFloatingBus();
|
||||
}
|
||||
|
||||
private int ReadIoRegionC1C7(int address)
|
||||
{
|
||||
_slotRegionC8CF = (address >> 8) & 0x07;
|
||||
return IsRomC1CFInternal ? _romInternalRegionC1CF[address - 0xC100] : Machine.Slots[_slotRegionC8CF].ReadIoRegionC1C7(address);
|
||||
}
|
||||
|
||||
private int ReadIoRegionC3C3(int address)
|
||||
{
|
||||
_slotRegionC8CF = (address >> 8) & 0x07;
|
||||
if (!IsRomC3C3External)
|
||||
{
|
||||
SetRomC8CF(true); // $C3XX sets IntC8Rom; inhibits I/O Strobe' [5-28, 7-21]
|
||||
}
|
||||
return _noSlotClock.Read(address, (IsRomC1CFInternal || !IsRomC3C3External) ? _romInternalRegionC1CF[address - 0xC100] : Machine.Slot3.ReadIoRegionC1C7(address));
|
||||
}
|
||||
|
||||
private int ReadIoRegionC8CF(int address)
|
||||
{
|
||||
if (address == 0xCFFF)
|
||||
{
|
||||
SetRomC8CF(false); // $CFFF resets IntC8Rom [5-28, 7-21]
|
||||
}
|
||||
return (IsRomC1CFInternal || IsRomC8CFInternal) ? _romInternalRegionC1CF[address - 0xC100] : Machine.Slots[_slotRegionC8CF].ReadIoRegionC8CF(address);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "address-512")]
|
||||
|
@ -351,7 +390,7 @@ namespace Jellyfish.Virtu
|
|||
#region Write Actions
|
||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
||||
private void WriteIoC0XX(int address, byte data)
|
||||
private void WriteIoRegionC0C0(int address, byte data)
|
||||
{
|
||||
switch (address)
|
||||
{
|
||||
|
@ -368,7 +407,7 @@ namespace Jellyfish.Virtu
|
|||
break;
|
||||
|
||||
case 0xC006: case 0xC007:
|
||||
SetRomCXXX(TestBit(address, 0));
|
||||
SetRomC1CF(TestBit(address, 0));
|
||||
break;
|
||||
|
||||
case 0xC008: case 0xC009:
|
||||
|
@ -376,7 +415,7 @@ namespace Jellyfish.Virtu
|
|||
break;
|
||||
|
||||
case 0xC00A: case 0xC00B:
|
||||
SetRomC3XX(TestBit(address, 0));
|
||||
SetRomC3C3(TestBit(address, 0));
|
||||
break;
|
||||
|
||||
case 0xC00C: case 0xC00D: // [7-5]
|
||||
|
@ -455,31 +494,37 @@ namespace Jellyfish.Virtu
|
|||
|
||||
case 0xC090: case 0xC091: case 0xC092: case 0xC093: case 0xC094: case 0xC095: case 0xC096: case 0xC097: // slot1
|
||||
case 0xC098: case 0xC099: case 0xC09A: case 0xC09B: case 0xC09C: case 0xC09D: case 0xC09E: case 0xC09F:
|
||||
Machine.Slot1.WriteIoRegionC0C0(address, data);
|
||||
break;
|
||||
|
||||
case 0xC0A0: case 0xC0A1: case 0xC0A2: case 0xC0A3: case 0xC0A4: case 0xC0A5: case 0xC0A6: case 0xC0A7: // slot2
|
||||
case 0xC0A8: case 0xC0A9: case 0xC0AA: case 0xC0AB: case 0xC0AC: case 0xC0AD: case 0xC0AE: case 0xC0AF:
|
||||
Machine.Slot2.WriteIoRegionC0C0(address, data);
|
||||
break;
|
||||
|
||||
case 0xC0B0: case 0xC0B1: case 0xC0B2: case 0xC0B3: case 0xC0B4: case 0xC0B5: case 0xC0B6: case 0xC0B7: // slot3
|
||||
case 0xC0B8: case 0xC0B9: case 0xC0BA: case 0xC0BB: case 0xC0BC: case 0xC0BD: case 0xC0BE: case 0xC0BF:
|
||||
Machine.Slot3.WriteIoRegionC0C0(address, data);
|
||||
break;
|
||||
|
||||
case 0xC0C0: case 0xC0C1: case 0xC0C2: case 0xC0C3: case 0xC0C4: case 0xC0C5: case 0xC0C6: case 0xC0C7: // slot4
|
||||
case 0xC0C8: case 0xC0C9: case 0xC0CA: case 0xC0CB: case 0xC0CC: case 0xC0CD: case 0xC0CE: case 0xC0CF:
|
||||
Machine.Slot4.WriteIoRegionC0C0(address, data);
|
||||
break;
|
||||
|
||||
case 0xC0D0: case 0xC0D1: case 0xC0D2: case 0xC0D3: case 0xC0D4: case 0xC0D5: case 0xC0D6: case 0xC0D7: // slot5
|
||||
case 0xC0D8: case 0xC0D9: case 0xC0DA: case 0xC0DB: case 0xC0DC: case 0xC0DD: case 0xC0DE: case 0xC0DF:
|
||||
Machine.Slot5.WriteIoRegionC0C0(address, data);
|
||||
break;
|
||||
|
||||
case 0xC0E0: case 0xC0E1: case 0xC0E2: case 0xC0E3: case 0xC0E4: case 0xC0E5: case 0xC0E6: case 0xC0E7: // slot6
|
||||
case 0xC0E8: case 0xC0E9: case 0xC0EA: case 0xC0EB: case 0xC0EC: case 0xC0ED: case 0xC0EE: case 0xC0EF:
|
||||
_diskII.Write(address, data);
|
||||
Machine.Slot6.WriteIoRegionC0C0(address, data);
|
||||
break;
|
||||
|
||||
case 0xC0F0: case 0xC0F1: case 0xC0F2: case 0xC0F3: case 0xC0F4: case 0xC0F5: case 0xC0F6: case 0xC0F7: // slot7
|
||||
case 0xC0F8: case 0xC0F9: case 0xC0FA: case 0xC0FB: case 0xC0FC: case 0xC0FD: case 0xC0FE: case 0xC0FF:
|
||||
Machine.Slot7.WriteIoRegionC0C0(address, data);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -487,6 +532,41 @@ namespace Jellyfish.Virtu
|
|||
}
|
||||
}
|
||||
|
||||
private void WriteIoRegionC1C7(int address, byte data)
|
||||
{
|
||||
_slotRegionC8CF = (address >> 8) & 0x07;
|
||||
if (!IsRomC1CFInternal)
|
||||
{
|
||||
Machine.Slots[_slotRegionC8CF].WriteIoRegionC1C7(address, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteIoRegionC3C3(int address, byte data)
|
||||
{
|
||||
_slotRegionC8CF = (address >> 8) & 0x07;
|
||||
if (!IsRomC3C3External)
|
||||
{
|
||||
SetRomC8CF(true); // $C3XX sets IntC8Rom; inhibits I/O Strobe' [5-28, 7-21]
|
||||
}
|
||||
else if (!IsRomC1CFInternal)
|
||||
{
|
||||
Machine.Slot3.WriteIoRegionC1C7(address, data);
|
||||
}
|
||||
_noSlotClock.Write(address);
|
||||
}
|
||||
|
||||
private void WriteIoRegionC8CF(int address, byte data)
|
||||
{
|
||||
if (address == 0xCFFF)
|
||||
{
|
||||
SetRomC8CF(false); // $CFFF resets IntC8Rom [5-28, 7-21]
|
||||
}
|
||||
if (!IsRomC1CFInternal && !IsRomC8CFInternal)
|
||||
{
|
||||
Machine.Slots[_slotRegionC8CF].WriteIoRegionC8CF(address, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteRamMode0MainRegion0407(int address, byte data)
|
||||
{
|
||||
if (_ramMainRegion02BF[address - 0x0200] != data)
|
||||
|
@ -991,7 +1071,7 @@ namespace Jellyfish.Virtu
|
|||
}
|
||||
}
|
||||
|
||||
private void WriteRomRegionC1FF(int address, byte data)
|
||||
private void WriteRomRegionD0FF(int address, byte data)
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
@ -1100,7 +1180,7 @@ namespace Jellyfish.Virtu
|
|||
private void MapRegionC0CF()
|
||||
{
|
||||
_regionRead[RegionC0C0] = null;
|
||||
if (IsRomCXXXInternal)
|
||||
if (IsRomC1CFInternal)
|
||||
{
|
||||
_regionRead[RegionC1C7] = _romInternalRegionC1CF;
|
||||
_regionRead[RegionC3C3] = _romInternalRegionC1CF;
|
||||
|
@ -1109,17 +1189,17 @@ namespace Jellyfish.Virtu
|
|||
else
|
||||
{
|
||||
_regionRead[RegionC1C7] = _romExternalRegionC1CF;
|
||||
_regionRead[RegionC3C3] = IsRomC3XXExternal ? _romExternalRegionC1CF : _romInternalRegionC1CF;
|
||||
_regionRead[RegionC8CF] = _romExternalRegionC1CF;
|
||||
_regionRead[RegionC3C3] = IsRomC3C3External ? _romExternalRegionC1CF : _romInternalRegionC1CF;
|
||||
_regionRead[RegionC8CF] = !IsRomC8CFInternal ? _romExternalRegionC1CF : _romInternalRegionC1CF;
|
||||
}
|
||||
_regionWrite[RegionC0C0] = null;
|
||||
_regionWrite[RegionC1C7] = null;
|
||||
_regionWrite[RegionC3C3] = null;
|
||||
_regionWrite[RegionC8CF] = null;
|
||||
_writeRegion[RegionC0C0] = WriteIoC0XX;
|
||||
_writeRegion[RegionC1C7] = WriteRomRegionC1FF;
|
||||
_writeRegion[RegionC3C3] = WriteRomRegionC1FF;
|
||||
_writeRegion[RegionC8CF] = WriteRomRegionC1FF;
|
||||
_writeRegion[RegionC0C0] = WriteIoRegionC0C0;
|
||||
_writeRegion[RegionC1C7] = WriteIoRegionC1C7;
|
||||
_writeRegion[RegionC3C3] = WriteIoRegionC3C3;
|
||||
_writeRegion[RegionC8CF] = WriteIoRegionC8CF;
|
||||
}
|
||||
|
||||
private void MapRegionD0FF()
|
||||
|
@ -1161,8 +1241,8 @@ namespace Jellyfish.Virtu
|
|||
{
|
||||
_regionWrite[RegionD0DF] = null;
|
||||
_regionWrite[RegionE0FF] = null;
|
||||
_writeRegion[RegionD0DF] = WriteRomRegionC1FF;
|
||||
_writeRegion[RegionE0FF] = WriteRomRegionC1FF;
|
||||
_writeRegion[RegionD0DF] = WriteRomRegionD0FF;
|
||||
_writeRegion[RegionE0FF] = WriteRomRegionD0FF;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1315,7 +1395,16 @@ namespace Jellyfish.Virtu
|
|||
}
|
||||
}
|
||||
|
||||
private void SetRomC3XX(bool value)
|
||||
private void SetRomC1CF(bool value)
|
||||
{
|
||||
if (!TestState(StateIntCXRom, value))
|
||||
{
|
||||
SetState(StateIntCXRom, value);
|
||||
MapRegionC0CF();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetRomC3C3(bool value)
|
||||
{
|
||||
if (!TestState(StateSlotC3Rom, value))
|
||||
{
|
||||
|
@ -1324,11 +1413,11 @@ namespace Jellyfish.Virtu
|
|||
}
|
||||
}
|
||||
|
||||
private void SetRomCXXX(bool value)
|
||||
private void SetRomC8CF(bool value)
|
||||
{
|
||||
if (!TestState(StateIntCXRom, value))
|
||||
if (!TestState(StateIntC8Rom, value))
|
||||
{
|
||||
SetState(StateIntCXRom, value);
|
||||
SetState(StateIntC8Rom, value);
|
||||
MapRegionC0CF();
|
||||
}
|
||||
}
|
||||
|
@ -1427,8 +1516,9 @@ namespace Jellyfish.Virtu
|
|||
public bool IsRamWriteAux { get { return TestState(StateRamWrt); } }
|
||||
public bool IsRamWriteAuxRegion0407 { get { return Is80Store ? IsPage2 : IsRamWriteAux; } }
|
||||
public bool IsRamWriteAuxRegion203F { get { return TestState(State80Store | StateHires, State80Store | StateHires) ? IsPage2 : IsRamWriteAux; } }
|
||||
public bool IsRomC3XXExternal { get { return TestState(StateSlotC3Rom); } }
|
||||
public bool IsRomCXXXInternal { get { return TestState(StateIntCXRom); } }
|
||||
public bool IsRomC1CFInternal { get { return TestState(StateIntCXRom); } }
|
||||
public bool IsRomC3C3External { get { return TestState(StateSlotC3Rom); } }
|
||||
public bool IsRomC8CFInternal { get { return TestState(StateIntC8Rom); } }
|
||||
public bool IsText { get { return TestState(StateText); } }
|
||||
public bool IsVideoPage2 { get { return TestState(State80Store | StatePage2, StatePage2); } } // 80Store inhibits video Page2 [5-7, 8-19]
|
||||
public bool IsZeroPageAux { get { return TestState(StateAltZP); } }
|
||||
|
@ -1436,14 +1526,15 @@ namespace Jellyfish.Virtu
|
|||
public MonitorType Monitor { get; private set; }
|
||||
public int VideoMode { get { return StateVideoMode[_state & StateVideo]; } }
|
||||
|
||||
private DiskII _diskII;
|
||||
private Keyboard _keyboard;
|
||||
private GamePort _gamePort;
|
||||
private Cassette _cassette;
|
||||
private Speaker _speaker;
|
||||
private Video _video;
|
||||
private NoSlotClock _noSlotClock;
|
||||
|
||||
private int _state;
|
||||
private int _slotRegionC8CF;
|
||||
|
||||
private byte[] _zeroPage;
|
||||
private byte[][] _regionRead = new byte[RegionCount][];
|
||||
|
|
|
@ -83,11 +83,12 @@ namespace Jellyfish.Virtu
|
|||
private const int StateRamRd = 0x002000;
|
||||
private const int StateRamWrt = 0x004000;
|
||||
private const int StateSlotC3Rom = 0x008000;
|
||||
private const int StateIntCXRom = 0x010000;
|
||||
private const int StateAn0 = 0x020000;
|
||||
private const int StateAn1 = 0x040000;
|
||||
private const int StateAn2 = 0x080000;
|
||||
private const int StateAn3 = 0x100000;
|
||||
private const int StateIntC8Rom = 0x010000; // [5-28]
|
||||
private const int StateIntCXRom = 0x020000;
|
||||
private const int StateAn0 = 0x040000;
|
||||
private const int StateAn1 = 0x080000;
|
||||
private const int StateAn2 = 0x100000;
|
||||
private const int StateAn3 = 0x200000;
|
||||
private const int StateVideo = State80Col | StateText | StateMixed | StateHires | StateDRes;
|
||||
|
||||
private const int StateVideoModeCount = 32;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
namespace Jellyfish.Virtu
|
||||
{
|
||||
public sealed class NoSlotClock
|
||||
{
|
||||
public NoSlotClock()
|
||||
{
|
||||
}
|
||||
|
||||
public int Read(int address, int data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
public void Write(int address)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
namespace Jellyfish.Virtu
|
||||
{
|
||||
public class PeripheralCard : MachineComponent
|
||||
{
|
||||
public PeripheralCard(Machine machine) :
|
||||
base(machine)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int ReadIoRegionC0C0(int address)
|
||||
{
|
||||
// read Device Select' address $C0nX; n = slot number + 8
|
||||
return ReadFloatingBus();
|
||||
}
|
||||
|
||||
public virtual int ReadIoRegionC1C7(int address)
|
||||
{
|
||||
// read I/O Select' address $CsXX; s = slot number
|
||||
return ReadFloatingBus();
|
||||
}
|
||||
|
||||
public virtual int ReadIoRegionC8CF(int address)
|
||||
{
|
||||
// read I/O Strobe' address $C800-$CFFF
|
||||
return ReadFloatingBus();
|
||||
}
|
||||
|
||||
public virtual void WriteIoRegionC0C0(int address, int data)
|
||||
{
|
||||
// write Device Select' address $C0nX; n = slot number + 8
|
||||
}
|
||||
|
||||
public virtual void WriteIoRegionC1C7(int address, int data)
|
||||
{
|
||||
// write I/O Select' address $CsXX; s = slot number
|
||||
}
|
||||
|
||||
public virtual void WriteIoRegionC8CF(int address, int data)
|
||||
{
|
||||
// write I/O Strobe' address $C800-$CFFF
|
||||
}
|
||||
|
||||
protected int ReadFloatingBus()
|
||||
{
|
||||
return Machine.Video.ReadFloatingBus();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,9 @@
|
|||
}
|
||||
|
||||
public bool IsAnyKeyDown { get; protected set; }
|
||||
public bool IsControlKeyDown { get; protected set; }
|
||||
public bool IsShiftKeyDown { get; protected set; }
|
||||
|
||||
public bool IsOpenAppleKeyDown { get; protected set; }
|
||||
public bool IsCloseAppleKeyDown { get; protected set; }
|
||||
|
||||
|
|
|
@ -128,15 +128,15 @@
|
|||
<Compile Include="..\DiskDsk.cs">
|
||||
<Link>Core\DiskDsk.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskII.cs">
|
||||
<Link>Core\DiskII.cs</Link>
|
||||
<Compile Include="..\DiskIIController.cs">
|
||||
<Link>Core\DiskIIController.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskIIDrive.cs">
|
||||
<Link>Core\DiskIIDrive.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskNib.cs">
|
||||
<Link>Core\DiskNib.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Drive525.cs">
|
||||
<Link>Core\Drive525.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\GamePort.cs">
|
||||
<Link>Core\GamePort.cs</Link>
|
||||
</Compile>
|
||||
|
@ -164,6 +164,12 @@
|
|||
<Compile Include="..\MemoryData.cs">
|
||||
<Link>Core\MemoryData.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\NoSlotClock.cs">
|
||||
<Link>Core\NoSlotClock.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\PeripheralCard.cs">
|
||||
<Link>Core\PeripheralCard.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||
<Link>Properties\Strings.Designer.cs</Link>
|
||||
<AutoGen>True</AutoGen>
|
||||
|
|
|
@ -73,7 +73,11 @@ namespace Jellyfish.Virtu
|
|||
using (var stream = dialog.File.OpenRead())
|
||||
{
|
||||
_machine.Pause();
|
||||
_machine.DiskII.Drives[drive].InsertDisk(dialog.File.Name, stream, false);
|
||||
var diskII = _machine.FindDiskIIController();
|
||||
if (diskII != null)
|
||||
{
|
||||
diskII.Drives[drive].InsertDisk(dialog.File.Name, stream, false);
|
||||
}
|
||||
_machine.Unpause();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,15 +113,15 @@
|
|||
<Compile Include="..\..\DiskDsk.cs">
|
||||
<Link>Core\DiskDsk.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\DiskII.cs">
|
||||
<Link>Core\DiskII.cs</Link>
|
||||
<Compile Include="..\..\DiskIIController.cs">
|
||||
<Link>Core\DiskIIController.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\DiskIIDrive.cs">
|
||||
<Link>Core\DiskIIDrive.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\DiskNib.cs">
|
||||
<Link>Core\DiskNib.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\Drive525.cs">
|
||||
<Link>Core\Drive525.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\GamePort.cs">
|
||||
<Link>Core\GamePort.cs</Link>
|
||||
</Compile>
|
||||
|
@ -149,6 +149,12 @@
|
|||
<Compile Include="..\..\MemoryData.cs">
|
||||
<Link>Core\MemoryData.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\NoSlotClock.cs">
|
||||
<Link>Core\NoSlotClock.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\PeripheralCard.cs">
|
||||
<Link>Core\PeripheralCard.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\Properties\Strings.Designer.cs">
|
||||
<Link>Properties\Strings.Designer.cs</Link>
|
||||
<AutoGen>True</AutoGen>
|
||||
|
|
|
@ -44,11 +44,12 @@ namespace Jellyfish.Virtu.Services
|
|||
}
|
||||
|
||||
var modifiers = System.Windows.Input.Keyboard.Modifiers;
|
||||
bool control = ((modifiers & ModifierKeys.Control) != 0);
|
||||
IsControlKeyDown = ((modifiers & ModifierKeys.Control) != 0);
|
||||
IsShiftKeyDown = ((modifiers & ModifierKeys.Shift) != 0);
|
||||
|
||||
IsOpenAppleKeyDown = ((modifiers & ModifierKeys.Alt) != 0) || IsKeyDown(Key.NumPad0);
|
||||
IsCloseAppleKeyDown = ((modifiers & ModifierKeys.Windows) != 0) || IsKeyDown(Key.Decimal);
|
||||
IsResetKeyDown = control && IsKeyDown(Key.Back);
|
||||
IsResetKeyDown = IsControlKeyDown && IsKeyDown(Key.Back);
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace Jellyfish.Virtu
|
|||
}
|
||||
}
|
||||
|
||||
public int ReadFloatingBus()
|
||||
public int ReadFloatingBus() // [5-40]
|
||||
{
|
||||
// derive scanner counters from current cycles into frame; assumes hcount and vcount preset at start of frame [3-13, 3-15, 3-16]
|
||||
int cycles = _cyclesPerVSync - Machine.Events.FindEvent(_resetVSyncEvent);
|
||||
|
|
|
@ -118,15 +118,15 @@
|
|||
<Compile Include="..\DiskDsk.cs">
|
||||
<Link>Core\DiskDsk.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskII.cs">
|
||||
<Link>Core\DiskII.cs</Link>
|
||||
<Compile Include="..\DiskIIController.cs">
|
||||
<Link>Core\DiskIIController.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskIIDrive.cs">
|
||||
<Link>Core\DiskIIDrive.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskNib.cs">
|
||||
<Link>Core\DiskNib.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Drive525.cs">
|
||||
<Link>Core\Drive525.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\GamePort.cs">
|
||||
<Link>Core\GamePort.cs</Link>
|
||||
</Compile>
|
||||
|
@ -154,6 +154,12 @@
|
|||
<Compile Include="..\MemoryData.cs">
|
||||
<Link>Core\MemoryData.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\NoSlotClock.cs">
|
||||
<Link>Core\NoSlotClock.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\PeripheralCard.cs">
|
||||
<Link>Core\PeripheralCard.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||
<Link>Properties\Strings.Designer.cs</Link>
|
||||
<AutoGen>True</AutoGen>
|
||||
|
|
|
@ -75,15 +75,19 @@ namespace Jellyfish.Virtu
|
|||
using (var stream = File.OpenRead(dialog.FileName))
|
||||
{
|
||||
_machine.Pause();
|
||||
_machine.DiskII.Drives[drive].InsertDisk(dialog.FileName, stream, false);
|
||||
var settings = _machine.Settings.DiskII;
|
||||
if (drive == 0)
|
||||
var diskII = _machine.FindDiskIIController();
|
||||
if (diskII != null)
|
||||
{
|
||||
settings.Disk1.Name = dialog.FileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.Disk2.Name = dialog.FileName;
|
||||
diskII.Drives[drive].InsertDisk(dialog.FileName, stream, false);
|
||||
var settings = _machine.Settings.DiskII;
|
||||
if (drive == 0)
|
||||
{
|
||||
settings.Disk1.Name = dialog.FileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.Disk2.Name = dialog.FileName;
|
||||
}
|
||||
}
|
||||
_machine.Unpause();
|
||||
}
|
||||
|
|
|
@ -44,11 +44,12 @@ namespace Jellyfish.Virtu.Services
|
|||
}
|
||||
}
|
||||
|
||||
bool control = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
|
||||
IsControlKeyDown = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
|
||||
IsShiftKeyDown = ((keyboard.Modifiers & ModifierKeys.Shift) != 0);
|
||||
|
||||
IsOpenAppleKeyDown = keyboard.IsKeyDown(Key.LeftAlt) || IsKeyDown(Key.NumPad0);
|
||||
IsCloseAppleKeyDown = keyboard.IsKeyDown(Key.RightAlt) || IsKeyDown(Key.Decimal);
|
||||
IsResetKeyDown = control && keyboard.IsKeyDown(Key.Back);
|
||||
IsResetKeyDown = IsControlKeyDown && keyboard.IsKeyDown(Key.Back);
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
|
|
@ -122,15 +122,15 @@
|
|||
<Compile Include="..\DiskDsk.cs">
|
||||
<Link>Core\DiskDsk.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskII.cs">
|
||||
<Link>Core\DiskII.cs</Link>
|
||||
<Compile Include="..\DiskIIController.cs">
|
||||
<Link>Core\DiskIIController.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskIIDrive.cs">
|
||||
<Link>Core\DiskIIDrive.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskNib.cs">
|
||||
<Link>Core\DiskNib.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Drive525.cs">
|
||||
<Link>Core\Drive525.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\GamePort.cs">
|
||||
<Link>Core\GamePort.cs</Link>
|
||||
</Compile>
|
||||
|
@ -158,6 +158,12 @@
|
|||
<Compile Include="..\MemoryData.cs">
|
||||
<Link>Core\MemoryData.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\NoSlotClock.cs">
|
||||
<Link>Core\NoSlotClock.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\PeripheralCard.cs">
|
||||
<Link>Core\PeripheralCard.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||
<Link>Properties\Strings.Designer.cs</Link>
|
||||
<AutoGen>True</AutoGen>
|
||||
|
|
|
@ -128,15 +128,15 @@
|
|||
<Compile Include="..\DiskDsk.cs">
|
||||
<Link>Core\DiskDsk.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskII.cs">
|
||||
<Link>Core\DiskII.cs</Link>
|
||||
<Compile Include="..\DiskIIController.cs">
|
||||
<Link>Core\DiskIIController.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskIIDrive.cs">
|
||||
<Link>Core\DiskIIDrive.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskNib.cs">
|
||||
<Link>Core\DiskNib.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Drive525.cs">
|
||||
<Link>Core\Drive525.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\GamePort.cs">
|
||||
<Link>Core\GamePort.cs</Link>
|
||||
</Compile>
|
||||
|
@ -164,6 +164,12 @@
|
|||
<Compile Include="..\MemoryData.cs">
|
||||
<Link>Core\MemoryData.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\NoSlotClock.cs">
|
||||
<Link>Core\NoSlotClock.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\PeripheralCard.cs">
|
||||
<Link>Core\PeripheralCard.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||
<Link>Properties\Strings.Designer.cs</Link>
|
||||
<AutoGen>True</AutoGen>
|
||||
|
|
|
@ -132,15 +132,15 @@
|
|||
<Compile Include="..\DiskDsk.cs">
|
||||
<Link>Core\DiskDsk.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskII.cs">
|
||||
<Link>Core\DiskII.cs</Link>
|
||||
<Compile Include="..\DiskIIController.cs">
|
||||
<Link>Core\DiskIIController.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskIIDrive.cs">
|
||||
<Link>Core\DiskIIDrive.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DiskNib.cs">
|
||||
<Link>Core\DiskNib.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Drive525.cs">
|
||||
<Link>Core\Drive525.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\GamePort.cs">
|
||||
<Link>Core\GamePort.cs</Link>
|
||||
</Compile>
|
||||
|
@ -168,6 +168,12 @@
|
|||
<Compile Include="..\MemoryData.cs">
|
||||
<Link>Core\MemoryData.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\NoSlotClock.cs">
|
||||
<Link>Core\NoSlotClock.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\PeripheralCard.cs">
|
||||
<Link>Core\PeripheralCard.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||
<Link>Properties\Strings.Designer.cs</Link>
|
||||
<AutoGen>True</AutoGen>
|
||||
|
|
|
@ -67,11 +67,12 @@ namespace Jellyfish.Virtu.Services
|
|||
}
|
||||
}
|
||||
|
||||
bool control = IsKeyDown(Keys.LeftControl) || IsKeyDown(Keys.RightControl);
|
||||
IsControlKeyDown = IsKeyDown(Keys.LeftControl) || IsKeyDown(Keys.RightControl);
|
||||
IsShiftKeyDown = IsKeyDown(Keys.LeftShift) || IsKeyDown(Keys.RightShift);
|
||||
|
||||
IsOpenAppleKeyDown = IsKeyDown(Keys.LeftAlt) || IsKeyDown(Keys.NumPad0) || (gamePadState.Buttons.LeftShoulder == ButtonState.Pressed);
|
||||
IsCloseAppleKeyDown = IsKeyDown(Keys.RightAlt) || IsKeyDown(Keys.Decimal) || (gamePadState.Buttons.RightShoulder == ButtonState.Pressed);
|
||||
IsResetKeyDown = (control && IsKeyDown(Keys.Back)) || (gamePadControl && (gamePadState.Buttons.Start == ButtonState.Pressed));
|
||||
IsResetKeyDown = (IsControlKeyDown && IsKeyDown(Keys.Back)) || (gamePadControl && (gamePadState.Buttons.Start == ButtonState.Pressed));
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue