mirror of
https://github.com/digital-jellyfish/Virtu.git
synced 2024-06-02 12:41:31 +00:00
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>
|
<Dictionary>
|
||||||
<Acronyms>
|
<Acronyms>
|
||||||
<CasingExceptions>
|
<CasingExceptions>
|
||||||
<Acronym>CXXX</Acronym>
|
<Acronym>Io</Acronym>
|
||||||
<Acronym>RPC</Acronym>
|
<Acronym>RPC</Acronym>
|
||||||
</CasingExceptions>
|
</CasingExceptions>
|
||||||
</Acronyms>
|
</Acronyms>
|
||||||
|
|
251
Virtu/DiskIIController.cs
Normal file
251
Virtu/DiskIIController.cs
Normal file
|
@ -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];
|
||||||
|
}
|
||||||
|
}
|
120
Virtu/DiskIIDrive.cs
Normal file
120
Virtu/DiskIIDrive.cs
Normal file
|
@ -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 @@ public bool ReadButton2()
|
||||||
{
|
{
|
||||||
var settings = Machine.Settings.GamePort;
|
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)));
|
(settings.UseKeyboard && (settings.Key.Button2 > 0) && _keyboardService.IsKeyDown(settings.Key.Button2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,24 @@ public Machine()
|
||||||
|
|
||||||
Cpu = new Cpu(this);
|
Cpu = new Cpu(this);
|
||||||
Memory = new Memory(this);
|
Memory = new Memory(this);
|
||||||
DiskII = new DiskII(this);
|
|
||||||
Keyboard = new Keyboard(this);
|
Keyboard = new Keyboard(this);
|
||||||
GamePort = new GamePort(this);
|
GamePort = new GamePort(this);
|
||||||
Cassette = new Cassette(this);
|
Cassette = new Cassette(this);
|
||||||
Speaker = new Speaker(this);
|
Speaker = new Speaker(this);
|
||||||
Video = new Video(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" };
|
Thread = new Thread(Run) { Name = "Machine" };
|
||||||
}
|
}
|
||||||
|
@ -76,6 +87,20 @@ public void Stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
private void Run() // machine thread
|
||||||
{
|
{
|
||||||
Components.ForEach(component => component.Initialize());
|
Components.ForEach(component => component.Initialize());
|
||||||
|
@ -108,12 +133,22 @@ private void Run() // machine thread
|
||||||
|
|
||||||
public Cpu Cpu { get; private set; }
|
public Cpu Cpu { get; private set; }
|
||||||
public Memory Memory { get; private set; }
|
public Memory Memory { get; private set; }
|
||||||
public DiskII DiskII { get; private set; }
|
|
||||||
public Keyboard Keyboard { get; private set; }
|
public Keyboard Keyboard { get; private set; }
|
||||||
public GamePort GamePort { get; private set; }
|
public GamePort GamePort { get; private set; }
|
||||||
public Cassette Cassette { get; private set; }
|
public Cassette Cassette { get; private set; }
|
||||||
public Speaker Speaker { get; private set; }
|
public Speaker Speaker { get; private set; }
|
||||||
public Video Video { 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 Collection<MachineComponent> Components { get; private set; }
|
||||||
|
|
||||||
public Thread Thread { get; private set; }
|
public Thread Thread { get; private set; }
|
||||||
|
|
173
Virtu/Memory.cs
173
Virtu/Memory.cs
|
@ -81,12 +81,12 @@ public Memory(Machine machine) :
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_diskII = Machine.DiskII;
|
|
||||||
_keyboard = Machine.Keyboard;
|
_keyboard = Machine.Keyboard;
|
||||||
_gamePort = Machine.GamePort;
|
_gamePort = Machine.GamePort;
|
||||||
_cassette = Machine.Cassette;
|
_cassette = Machine.Cassette;
|
||||||
_speaker = Machine.Speaker;
|
_speaker = Machine.Speaker;
|
||||||
_video = Machine.Video;
|
_video = Machine.Video;
|
||||||
|
_noSlotClock = Machine.NoSlotClock;
|
||||||
|
|
||||||
var romStream = StorageService.GetResourceStream("Roms/AppleIIe.rom", 0x4000);
|
var romStream = StorageService.GetResourceStream("Roms/AppleIIe.rom", 0x4000);
|
||||||
romStream.Seek(0x0100, SeekOrigin.Current);
|
romStream.Seek(0x0100, SeekOrigin.Current);
|
||||||
|
@ -94,9 +94,6 @@ public override void Initialize()
|
||||||
romStream.ReadBlock(_romRegionD0DF, 0x0000, 0x1000);
|
romStream.ReadBlock(_romRegionD0DF, 0x0000, 0x1000);
|
||||||
romStream.ReadBlock(_romRegionE0FF, 0x0000, 0x2000);
|
romStream.ReadBlock(_romRegionE0FF, 0x0000, 0x2000);
|
||||||
|
|
||||||
romStream = StorageService.GetResourceStream("Roms/DiskII.rom", 0x0100);
|
|
||||||
romStream.ReadBlock(_romExternalRegionC1CF, 0x0500, 0x0100);
|
|
||||||
|
|
||||||
if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0xC1))
|
if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0xC1))
|
||||||
{
|
{
|
||||||
Monitor = MonitorType.Standard;
|
Monitor = MonitorType.Standard;
|
||||||
|
@ -105,14 +102,12 @@ public override void Initialize()
|
||||||
{
|
{
|
||||||
Monitor = MonitorType.Enhanced;
|
Monitor = MonitorType.Enhanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer.BlockCopy(_romInternalRegionC1CF, 0x0700, _romExternalRegionC1CF, 0x0700, 0x0800);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Reset() // [7-3]
|
public override void Reset() // [7-3]
|
||||||
{
|
{
|
||||||
ResetState(State80Col | State80Store | StateAltChrSet | StateAltZP | StateBank1 | StateHRamRd | StateHRamPreWrt | StateHRamWrt | // HRamWrt' [5-23]
|
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]
|
SetState(StateDRes); // An3' -> DRes [8-20]
|
||||||
|
|
||||||
MapRegion0001();
|
MapRegion0001();
|
||||||
|
@ -125,8 +120,7 @@ public override void Reset() // [7-3]
|
||||||
public int Read(int address)
|
public int Read(int address)
|
||||||
{
|
{
|
||||||
int region = PageRegion[address >> 8];
|
int region = PageRegion[address >> 8];
|
||||||
|
return ((address & 0xF000) != 0xC000) ? _regionRead[region][address - RegionBaseAddress[region]] : ReadIoRegionC0CF(address);
|
||||||
return (region == RegionC0C0) ? ReadIoC0XX(address) : _regionRead[region][address - RegionBaseAddress[region]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ReadZeroPage(int address)
|
public int ReadZeroPage(int address)
|
||||||
|
@ -154,9 +148,29 @@ public void WriteZeroPage(int address, int data)
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Read Actions
|
#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", "CA1502:AvoidExcessiveComplexity")]
|
||||||
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
||||||
private int ReadIoC0XX(int address)
|
private int ReadIoRegionC0C0(int address)
|
||||||
{
|
{
|
||||||
switch (address)
|
switch (address)
|
||||||
{
|
{
|
||||||
|
@ -181,13 +195,13 @@ private int ReadIoC0XX(int address)
|
||||||
return SetBit7(_keyboard.ReadLatch(), IsRamWriteAux);
|
return SetBit7(_keyboard.ReadLatch(), IsRamWriteAux);
|
||||||
|
|
||||||
case 0xC015:
|
case 0xC015:
|
||||||
return SetBit7(_keyboard.ReadLatch(), IsRomCXXXInternal);
|
return SetBit7(_keyboard.ReadLatch(), IsRomC1CFInternal);
|
||||||
|
|
||||||
case 0xC016:
|
case 0xC016:
|
||||||
return SetBit7(_keyboard.ReadLatch(), IsZeroPageAux);
|
return SetBit7(_keyboard.ReadLatch(), IsZeroPageAux);
|
||||||
|
|
||||||
case 0xC017:
|
case 0xC017:
|
||||||
return SetBit7(_keyboard.ReadLatch(), IsRomC3XXExternal);
|
return SetBit7(_keyboard.ReadLatch(), IsRomC3C3External);
|
||||||
|
|
||||||
case 0xC018:
|
case 0xC018:
|
||||||
return SetBit7(_keyboard.ReadLatch(), Is80Store);
|
return SetBit7(_keyboard.ReadLatch(), Is80Store);
|
||||||
|
@ -296,37 +310,62 @@ private int ReadIoC0XX(int address)
|
||||||
|
|
||||||
case 0xC090: case 0xC091: case 0xC092: case 0xC093: case 0xC094: case 0xC095: case 0xC096: case 0xC097: // slot1
|
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:
|
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 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:
|
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 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:
|
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 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:
|
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 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:
|
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 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:
|
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 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:
|
case 0xC0F8: case 0xC0F9: case 0xC0FA: case 0xC0FB: case 0xC0FC: case 0xC0FD: case 0xC0FE: case 0xC0FF:
|
||||||
break;
|
return Machine.Slot7.ReadIoRegionC0C0(address);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException("address");
|
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")]
|
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "address-512")]
|
||||||
|
@ -351,7 +390,7 @@ public int ReadRomRegionE0FF(int address)
|
||||||
#region Write Actions
|
#region Write Actions
|
||||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||||
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
||||||
private void WriteIoC0XX(int address, byte data)
|
private void WriteIoRegionC0C0(int address, byte data)
|
||||||
{
|
{
|
||||||
switch (address)
|
switch (address)
|
||||||
{
|
{
|
||||||
|
@ -368,7 +407,7 @@ private void WriteIoC0XX(int address, byte data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC006: case 0xC007:
|
case 0xC006: case 0xC007:
|
||||||
SetRomCXXX(TestBit(address, 0));
|
SetRomC1CF(TestBit(address, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC008: case 0xC009:
|
case 0xC008: case 0xC009:
|
||||||
|
@ -376,7 +415,7 @@ private void WriteIoC0XX(int address, byte data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC00A: case 0xC00B:
|
case 0xC00A: case 0xC00B:
|
||||||
SetRomC3XX(TestBit(address, 0));
|
SetRomC3C3(TestBit(address, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC00C: case 0xC00D: // [7-5]
|
case 0xC00C: case 0xC00D: // [7-5]
|
||||||
|
@ -455,31 +494,37 @@ private void WriteIoC0XX(int address, byte data)
|
||||||
|
|
||||||
case 0xC090: case 0xC091: case 0xC092: case 0xC093: case 0xC094: case 0xC095: case 0xC096: case 0xC097: // slot1
|
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:
|
case 0xC098: case 0xC099: case 0xC09A: case 0xC09B: case 0xC09C: case 0xC09D: case 0xC09E: case 0xC09F:
|
||||||
|
Machine.Slot1.WriteIoRegionC0C0(address, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC0A0: case 0xC0A1: case 0xC0A2: case 0xC0A3: case 0xC0A4: case 0xC0A5: case 0xC0A6: case 0xC0A7: // slot2
|
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:
|
case 0xC0A8: case 0xC0A9: case 0xC0AA: case 0xC0AB: case 0xC0AC: case 0xC0AD: case 0xC0AE: case 0xC0AF:
|
||||||
|
Machine.Slot2.WriteIoRegionC0C0(address, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC0B0: case 0xC0B1: case 0xC0B2: case 0xC0B3: case 0xC0B4: case 0xC0B5: case 0xC0B6: case 0xC0B7: // slot3
|
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:
|
case 0xC0B8: case 0xC0B9: case 0xC0BA: case 0xC0BB: case 0xC0BC: case 0xC0BD: case 0xC0BE: case 0xC0BF:
|
||||||
|
Machine.Slot3.WriteIoRegionC0C0(address, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC0C0: case 0xC0C1: case 0xC0C2: case 0xC0C3: case 0xC0C4: case 0xC0C5: case 0xC0C6: case 0xC0C7: // slot4
|
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:
|
case 0xC0C8: case 0xC0C9: case 0xC0CA: case 0xC0CB: case 0xC0CC: case 0xC0CD: case 0xC0CE: case 0xC0CF:
|
||||||
|
Machine.Slot4.WriteIoRegionC0C0(address, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC0D0: case 0xC0D1: case 0xC0D2: case 0xC0D3: case 0xC0D4: case 0xC0D5: case 0xC0D6: case 0xC0D7: // slot5
|
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:
|
case 0xC0D8: case 0xC0D9: case 0xC0DA: case 0xC0DB: case 0xC0DC: case 0xC0DD: case 0xC0DE: case 0xC0DF:
|
||||||
|
Machine.Slot5.WriteIoRegionC0C0(address, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC0E0: case 0xC0E1: case 0xC0E2: case 0xC0E3: case 0xC0E4: case 0xC0E5: case 0xC0E6: case 0xC0E7: // slot6
|
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:
|
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;
|
break;
|
||||||
|
|
||||||
case 0xC0F0: case 0xC0F1: case 0xC0F2: case 0xC0F3: case 0xC0F4: case 0xC0F5: case 0xC0F6: case 0xC0F7: // slot7
|
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:
|
case 0xC0F8: case 0xC0F9: case 0xC0FA: case 0xC0FB: case 0xC0FC: case 0xC0FD: case 0xC0FE: case 0xC0FF:
|
||||||
|
Machine.Slot7.WriteIoRegionC0C0(address, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -487,6 +532,41 @@ private void WriteIoC0XX(int address, byte data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
private void WriteRamMode0MainRegion0407(int address, byte data)
|
||||||
{
|
{
|
||||||
if (_ramMainRegion02BF[address - 0x0200] != data)
|
if (_ramMainRegion02BF[address - 0x0200] != data)
|
||||||
|
@ -991,7 +1071,7 @@ private void WriteRamModeFAuxRegion405F(int address, byte data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteRomRegionC1FF(int address, byte data)
|
private void WriteRomRegionD0FF(int address, byte data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -1100,7 +1180,7 @@ private void MapRegion203F()
|
||||||
private void MapRegionC0CF()
|
private void MapRegionC0CF()
|
||||||
{
|
{
|
||||||
_regionRead[RegionC0C0] = null;
|
_regionRead[RegionC0C0] = null;
|
||||||
if (IsRomCXXXInternal)
|
if (IsRomC1CFInternal)
|
||||||
{
|
{
|
||||||
_regionRead[RegionC1C7] = _romInternalRegionC1CF;
|
_regionRead[RegionC1C7] = _romInternalRegionC1CF;
|
||||||
_regionRead[RegionC3C3] = _romInternalRegionC1CF;
|
_regionRead[RegionC3C3] = _romInternalRegionC1CF;
|
||||||
|
@ -1109,17 +1189,17 @@ private void MapRegionC0CF()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_regionRead[RegionC1C7] = _romExternalRegionC1CF;
|
_regionRead[RegionC1C7] = _romExternalRegionC1CF;
|
||||||
_regionRead[RegionC3C3] = IsRomC3XXExternal ? _romExternalRegionC1CF : _romInternalRegionC1CF;
|
_regionRead[RegionC3C3] = IsRomC3C3External ? _romExternalRegionC1CF : _romInternalRegionC1CF;
|
||||||
_regionRead[RegionC8CF] = _romExternalRegionC1CF;
|
_regionRead[RegionC8CF] = !IsRomC8CFInternal ? _romExternalRegionC1CF : _romInternalRegionC1CF;
|
||||||
}
|
}
|
||||||
_regionWrite[RegionC0C0] = null;
|
_regionWrite[RegionC0C0] = null;
|
||||||
_regionWrite[RegionC1C7] = null;
|
_regionWrite[RegionC1C7] = null;
|
||||||
_regionWrite[RegionC3C3] = null;
|
_regionWrite[RegionC3C3] = null;
|
||||||
_regionWrite[RegionC8CF] = null;
|
_regionWrite[RegionC8CF] = null;
|
||||||
_writeRegion[RegionC0C0] = WriteIoC0XX;
|
_writeRegion[RegionC0C0] = WriteIoRegionC0C0;
|
||||||
_writeRegion[RegionC1C7] = WriteRomRegionC1FF;
|
_writeRegion[RegionC1C7] = WriteIoRegionC1C7;
|
||||||
_writeRegion[RegionC3C3] = WriteRomRegionC1FF;
|
_writeRegion[RegionC3C3] = WriteIoRegionC3C3;
|
||||||
_writeRegion[RegionC8CF] = WriteRomRegionC1FF;
|
_writeRegion[RegionC8CF] = WriteIoRegionC8CF;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MapRegionD0FF()
|
private void MapRegionD0FF()
|
||||||
|
@ -1161,8 +1241,8 @@ private void MapRegionD0FF()
|
||||||
{
|
{
|
||||||
_regionWrite[RegionD0DF] = null;
|
_regionWrite[RegionD0DF] = null;
|
||||||
_regionWrite[RegionE0FF] = null;
|
_regionWrite[RegionE0FF] = null;
|
||||||
_writeRegion[RegionD0DF] = WriteRomRegionC1FF;
|
_writeRegion[RegionD0DF] = WriteRomRegionD0FF;
|
||||||
_writeRegion[RegionE0FF] = WriteRomRegionC1FF;
|
_writeRegion[RegionE0FF] = WriteRomRegionD0FF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1315,7 +1395,16 @@ private void SetRamWrite(bool value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
if (!TestState(StateSlotC3Rom, value))
|
||||||
{
|
{
|
||||||
|
@ -1324,11 +1413,11 @@ private void SetRomC3XX(bool value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
MapRegionC0CF();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1427,8 +1516,9 @@ private bool TestState(int mask, int value)
|
||||||
public bool IsRamWriteAux { get { return TestState(StateRamWrt); } }
|
public bool IsRamWriteAux { get { return TestState(StateRamWrt); } }
|
||||||
public bool IsRamWriteAuxRegion0407 { get { return Is80Store ? IsPage2 : IsRamWriteAux; } }
|
public bool IsRamWriteAuxRegion0407 { get { return Is80Store ? IsPage2 : IsRamWriteAux; } }
|
||||||
public bool IsRamWriteAuxRegion203F { get { return TestState(State80Store | StateHires, State80Store | StateHires) ? IsPage2 : IsRamWriteAux; } }
|
public bool IsRamWriteAuxRegion203F { get { return TestState(State80Store | StateHires, State80Store | StateHires) ? IsPage2 : IsRamWriteAux; } }
|
||||||
public bool IsRomC3XXExternal { get { return TestState(StateSlotC3Rom); } }
|
public bool IsRomC1CFInternal { get { return TestState(StateIntCXRom); } }
|
||||||
public bool IsRomCXXXInternal { 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 IsText { get { return TestState(StateText); } }
|
||||||
public bool IsVideoPage2 { get { return TestState(State80Store | StatePage2, StatePage2); } } // 80Store inhibits video Page2 [5-7, 8-19]
|
public bool IsVideoPage2 { get { return TestState(State80Store | StatePage2, StatePage2); } } // 80Store inhibits video Page2 [5-7, 8-19]
|
||||||
public bool IsZeroPageAux { get { return TestState(StateAltZP); } }
|
public bool IsZeroPageAux { get { return TestState(StateAltZP); } }
|
||||||
|
@ -1436,14 +1526,15 @@ private bool TestState(int mask, int value)
|
||||||
public MonitorType Monitor { get; private set; }
|
public MonitorType Monitor { get; private set; }
|
||||||
public int VideoMode { get { return StateVideoMode[_state & StateVideo]; } }
|
public int VideoMode { get { return StateVideoMode[_state & StateVideo]; } }
|
||||||
|
|
||||||
private DiskII _diskII;
|
|
||||||
private Keyboard _keyboard;
|
private Keyboard _keyboard;
|
||||||
private GamePort _gamePort;
|
private GamePort _gamePort;
|
||||||
private Cassette _cassette;
|
private Cassette _cassette;
|
||||||
private Speaker _speaker;
|
private Speaker _speaker;
|
||||||
private Video _video;
|
private Video _video;
|
||||||
|
private NoSlotClock _noSlotClock;
|
||||||
|
|
||||||
private int _state;
|
private int _state;
|
||||||
|
private int _slotRegionC8CF;
|
||||||
|
|
||||||
private byte[] _zeroPage;
|
private byte[] _zeroPage;
|
||||||
private byte[][] _regionRead = new byte[RegionCount][];
|
private byte[][] _regionRead = new byte[RegionCount][];
|
||||||
|
|
|
@ -83,11 +83,12 @@ public partial class Memory
|
||||||
private const int StateRamRd = 0x002000;
|
private const int StateRamRd = 0x002000;
|
||||||
private const int StateRamWrt = 0x004000;
|
private const int StateRamWrt = 0x004000;
|
||||||
private const int StateSlotC3Rom = 0x008000;
|
private const int StateSlotC3Rom = 0x008000;
|
||||||
private const int StateIntCXRom = 0x010000;
|
private const int StateIntC8Rom = 0x010000; // [5-28]
|
||||||
private const int StateAn0 = 0x020000;
|
private const int StateIntCXRom = 0x020000;
|
||||||
private const int StateAn1 = 0x040000;
|
private const int StateAn0 = 0x040000;
|
||||||
private const int StateAn2 = 0x080000;
|
private const int StateAn1 = 0x080000;
|
||||||
private const int StateAn3 = 0x100000;
|
private const int StateAn2 = 0x100000;
|
||||||
|
private const int StateAn3 = 0x200000;
|
||||||
private const int StateVideo = State80Col | StateText | StateMixed | StateHires | StateDRes;
|
private const int StateVideo = State80Col | StateText | StateMixed | StateHires | StateDRes;
|
||||||
|
|
||||||
private const int StateVideoModeCount = 32;
|
private const int StateVideoModeCount = 32;
|
||||||
|
|
18
Virtu/NoSlotClock.cs
Normal file
18
Virtu/NoSlotClock.cs
Normal file
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
Virtu/PeripheralCard.cs
Normal file
48
Virtu/PeripheralCard.cs
Normal file
|
@ -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 virtual void Update() // main thread
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAnyKeyDown { get; protected set; }
|
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 IsOpenAppleKeyDown { get; protected set; }
|
||||||
public bool IsCloseAppleKeyDown { get; protected set; }
|
public bool IsCloseAppleKeyDown { get; protected set; }
|
||||||
|
|
||||||
|
|
|
@ -128,15 +128,15 @@
|
||||||
<Compile Include="..\DiskDsk.cs">
|
<Compile Include="..\DiskDsk.cs">
|
||||||
<Link>Core\DiskDsk.cs</Link>
|
<Link>Core\DiskDsk.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskII.cs">
|
<Compile Include="..\DiskIIController.cs">
|
||||||
<Link>Core\DiskII.cs</Link>
|
<Link>Core\DiskIIController.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\DiskIIDrive.cs">
|
||||||
|
<Link>Core\DiskIIDrive.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskNib.cs">
|
<Compile Include="..\DiskNib.cs">
|
||||||
<Link>Core\DiskNib.cs</Link>
|
<Link>Core\DiskNib.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Drive525.cs">
|
|
||||||
<Link>Core\Drive525.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\GamePort.cs">
|
<Compile Include="..\GamePort.cs">
|
||||||
<Link>Core\GamePort.cs</Link>
|
<Link>Core\GamePort.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -164,6 +164,12 @@
|
||||||
<Compile Include="..\MemoryData.cs">
|
<Compile Include="..\MemoryData.cs">
|
||||||
<Link>Core\MemoryData.cs</Link>
|
<Link>Core\MemoryData.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||||
<Link>Properties\Strings.Designer.cs</Link>
|
<Link>Properties\Strings.Designer.cs</Link>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|
|
@ -73,7 +73,11 @@ private void OnDiskButtonClick(int drive)
|
||||||
using (var stream = dialog.File.OpenRead())
|
using (var stream = dialog.File.OpenRead())
|
||||||
{
|
{
|
||||||
_machine.Pause();
|
_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();
|
_machine.Unpause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,15 +113,15 @@
|
||||||
<Compile Include="..\..\DiskDsk.cs">
|
<Compile Include="..\..\DiskDsk.cs">
|
||||||
<Link>Core\DiskDsk.cs</Link>
|
<Link>Core\DiskDsk.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\..\DiskII.cs">
|
<Compile Include="..\..\DiskIIController.cs">
|
||||||
<Link>Core\DiskII.cs</Link>
|
<Link>Core\DiskIIController.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\..\DiskIIDrive.cs">
|
||||||
|
<Link>Core\DiskIIDrive.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\..\DiskNib.cs">
|
<Compile Include="..\..\DiskNib.cs">
|
||||||
<Link>Core\DiskNib.cs</Link>
|
<Link>Core\DiskNib.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\..\Drive525.cs">
|
|
||||||
<Link>Core\Drive525.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\..\GamePort.cs">
|
<Compile Include="..\..\GamePort.cs">
|
||||||
<Link>Core\GamePort.cs</Link>
|
<Link>Core\GamePort.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -149,6 +149,12 @@
|
||||||
<Compile Include="..\..\MemoryData.cs">
|
<Compile Include="..\..\MemoryData.cs">
|
||||||
<Link>Core\MemoryData.cs</Link>
|
<Link>Core\MemoryData.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\..\Properties\Strings.Designer.cs">
|
||||||
<Link>Properties\Strings.Designer.cs</Link>
|
<Link>Properties\Strings.Designer.cs</Link>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|
|
@ -44,11 +44,12 @@ public override void Update() // main thread
|
||||||
}
|
}
|
||||||
|
|
||||||
var modifiers = System.Windows.Input.Keyboard.Modifiers;
|
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);
|
IsOpenAppleKeyDown = ((modifiers & ModifierKeys.Alt) != 0) || IsKeyDown(Key.NumPad0);
|
||||||
IsCloseAppleKeyDown = ((modifiers & ModifierKeys.Windows) != 0) || IsKeyDown(Key.Decimal);
|
IsCloseAppleKeyDown = ((modifiers & ModifierKeys.Windows) != 0) || IsKeyDown(Key.Decimal);
|
||||||
IsResetKeyDown = control && IsKeyDown(Key.Back);
|
IsResetKeyDown = IsControlKeyDown && IsKeyDown(Key.Back);
|
||||||
|
|
||||||
base.Update();
|
base.Update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ public void DirtyScreenText()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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]
|
// 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);
|
int cycles = _cyclesPerVSync - Machine.Events.FindEvent(_resetVSyncEvent);
|
||||||
|
|
|
@ -118,15 +118,15 @@
|
||||||
<Compile Include="..\DiskDsk.cs">
|
<Compile Include="..\DiskDsk.cs">
|
||||||
<Link>Core\DiskDsk.cs</Link>
|
<Link>Core\DiskDsk.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskII.cs">
|
<Compile Include="..\DiskIIController.cs">
|
||||||
<Link>Core\DiskII.cs</Link>
|
<Link>Core\DiskIIController.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\DiskIIDrive.cs">
|
||||||
|
<Link>Core\DiskIIDrive.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskNib.cs">
|
<Compile Include="..\DiskNib.cs">
|
||||||
<Link>Core\DiskNib.cs</Link>
|
<Link>Core\DiskNib.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Drive525.cs">
|
|
||||||
<Link>Core\Drive525.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\GamePort.cs">
|
<Compile Include="..\GamePort.cs">
|
||||||
<Link>Core\GamePort.cs</Link>
|
<Link>Core\GamePort.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -154,6 +154,12 @@
|
||||||
<Compile Include="..\MemoryData.cs">
|
<Compile Include="..\MemoryData.cs">
|
||||||
<Link>Core\MemoryData.cs</Link>
|
<Link>Core\MemoryData.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||||
<Link>Properties\Strings.Designer.cs</Link>
|
<Link>Properties\Strings.Designer.cs</Link>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|
|
@ -75,15 +75,19 @@ private void OnDiskButtonClick(int drive)
|
||||||
using (var stream = File.OpenRead(dialog.FileName))
|
using (var stream = File.OpenRead(dialog.FileName))
|
||||||
{
|
{
|
||||||
_machine.Pause();
|
_machine.Pause();
|
||||||
_machine.DiskII.Drives[drive].InsertDisk(dialog.FileName, stream, false);
|
var diskII = _machine.FindDiskIIController();
|
||||||
var settings = _machine.Settings.DiskII;
|
if (diskII != null)
|
||||||
if (drive == 0)
|
|
||||||
{
|
{
|
||||||
settings.Disk1.Name = dialog.FileName;
|
diskII.Drives[drive].InsertDisk(dialog.FileName, stream, false);
|
||||||
}
|
var settings = _machine.Settings.DiskII;
|
||||||
else
|
if (drive == 0)
|
||||||
{
|
{
|
||||||
settings.Disk2.Name = dialog.FileName;
|
settings.Disk1.Name = dialog.FileName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings.Disk2.Name = dialog.FileName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_machine.Unpause();
|
_machine.Unpause();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,12 @@ public override void Update() // main thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
IsOpenAppleKeyDown = keyboard.IsKeyDown(Key.LeftAlt) || IsKeyDown(Key.NumPad0);
|
||||||
IsCloseAppleKeyDown = keyboard.IsKeyDown(Key.RightAlt) || IsKeyDown(Key.Decimal);
|
IsCloseAppleKeyDown = keyboard.IsKeyDown(Key.RightAlt) || IsKeyDown(Key.Decimal);
|
||||||
IsResetKeyDown = control && keyboard.IsKeyDown(Key.Back);
|
IsResetKeyDown = IsControlKeyDown && keyboard.IsKeyDown(Key.Back);
|
||||||
|
|
||||||
base.Update();
|
base.Update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,15 +122,15 @@
|
||||||
<Compile Include="..\DiskDsk.cs">
|
<Compile Include="..\DiskDsk.cs">
|
||||||
<Link>Core\DiskDsk.cs</Link>
|
<Link>Core\DiskDsk.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskII.cs">
|
<Compile Include="..\DiskIIController.cs">
|
||||||
<Link>Core\DiskII.cs</Link>
|
<Link>Core\DiskIIController.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\DiskIIDrive.cs">
|
||||||
|
<Link>Core\DiskIIDrive.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskNib.cs">
|
<Compile Include="..\DiskNib.cs">
|
||||||
<Link>Core\DiskNib.cs</Link>
|
<Link>Core\DiskNib.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Drive525.cs">
|
|
||||||
<Link>Core\Drive525.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\GamePort.cs">
|
<Compile Include="..\GamePort.cs">
|
||||||
<Link>Core\GamePort.cs</Link>
|
<Link>Core\GamePort.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -158,6 +158,12 @@
|
||||||
<Compile Include="..\MemoryData.cs">
|
<Compile Include="..\MemoryData.cs">
|
||||||
<Link>Core\MemoryData.cs</Link>
|
<Link>Core\MemoryData.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||||
<Link>Properties\Strings.Designer.cs</Link>
|
<Link>Properties\Strings.Designer.cs</Link>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|
|
@ -128,15 +128,15 @@
|
||||||
<Compile Include="..\DiskDsk.cs">
|
<Compile Include="..\DiskDsk.cs">
|
||||||
<Link>Core\DiskDsk.cs</Link>
|
<Link>Core\DiskDsk.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskII.cs">
|
<Compile Include="..\DiskIIController.cs">
|
||||||
<Link>Core\DiskII.cs</Link>
|
<Link>Core\DiskIIController.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\DiskIIDrive.cs">
|
||||||
|
<Link>Core\DiskIIDrive.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskNib.cs">
|
<Compile Include="..\DiskNib.cs">
|
||||||
<Link>Core\DiskNib.cs</Link>
|
<Link>Core\DiskNib.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Drive525.cs">
|
|
||||||
<Link>Core\Drive525.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\GamePort.cs">
|
<Compile Include="..\GamePort.cs">
|
||||||
<Link>Core\GamePort.cs</Link>
|
<Link>Core\GamePort.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -164,6 +164,12 @@
|
||||||
<Compile Include="..\MemoryData.cs">
|
<Compile Include="..\MemoryData.cs">
|
||||||
<Link>Core\MemoryData.cs</Link>
|
<Link>Core\MemoryData.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||||
<Link>Properties\Strings.Designer.cs</Link>
|
<Link>Properties\Strings.Designer.cs</Link>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|
|
@ -132,15 +132,15 @@
|
||||||
<Compile Include="..\DiskDsk.cs">
|
<Compile Include="..\DiskDsk.cs">
|
||||||
<Link>Core\DiskDsk.cs</Link>
|
<Link>Core\DiskDsk.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskII.cs">
|
<Compile Include="..\DiskIIController.cs">
|
||||||
<Link>Core\DiskII.cs</Link>
|
<Link>Core\DiskIIController.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\DiskIIDrive.cs">
|
||||||
|
<Link>Core\DiskIIDrive.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskNib.cs">
|
<Compile Include="..\DiskNib.cs">
|
||||||
<Link>Core\DiskNib.cs</Link>
|
<Link>Core\DiskNib.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Drive525.cs">
|
|
||||||
<Link>Core\Drive525.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\GamePort.cs">
|
<Compile Include="..\GamePort.cs">
|
||||||
<Link>Core\GamePort.cs</Link>
|
<Link>Core\GamePort.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -168,6 +168,12 @@
|
||||||
<Compile Include="..\MemoryData.cs">
|
<Compile Include="..\MemoryData.cs">
|
||||||
<Link>Core\MemoryData.cs</Link>
|
<Link>Core\MemoryData.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||||
<Link>Properties\Strings.Designer.cs</Link>
|
<Link>Properties\Strings.Designer.cs</Link>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|
|
@ -67,11 +67,12 @@ public override void Update() // main thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
IsOpenAppleKeyDown = IsKeyDown(Keys.LeftAlt) || IsKeyDown(Keys.NumPad0) || (gamePadState.Buttons.LeftShoulder == ButtonState.Pressed);
|
||||||
IsCloseAppleKeyDown = IsKeyDown(Keys.RightAlt) || IsKeyDown(Keys.Decimal) || (gamePadState.Buttons.RightShoulder == 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();
|
base.Update();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user