2016-02-28 14:15:52 +00:00
|
|
|
|
using System.Collections.Generic;
|
2015-03-27 23:24:58 +00:00
|
|
|
|
using System.Linq;
|
2016-02-28 14:15:52 +00:00
|
|
|
|
|
2015-02-17 22:58:25 +00:00
|
|
|
|
using BizHawk.Emulation.Common;
|
|
|
|
|
using Jellyfish.Virtu;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|
|
|
|
{
|
2017-07-12 19:10:55 +00:00
|
|
|
|
[Core(
|
2015-02-17 22:58:25 +00:00
|
|
|
|
"Virtu",
|
2015-06-10 22:32:47 +00:00
|
|
|
|
"fool",
|
2015-02-17 22:58:25 +00:00
|
|
|
|
isPorted: true,
|
2017-04-24 13:21:05 +00:00
|
|
|
|
isReleased: true)]
|
2017-05-01 02:01:37 +00:00
|
|
|
|
[ServiceNotApplicable(typeof(ISaveRam), typeof(IRegionable), typeof(IBoardInfo))]
|
2016-12-11 17:14:42 +00:00
|
|
|
|
public partial class AppleII : IEmulator, ISoundProvider, IVideoProvider, IStatable, IDriveLight
|
2015-02-17 22:58:25 +00:00
|
|
|
|
{
|
2017-04-24 13:21:05 +00:00
|
|
|
|
static AppleII()
|
|
|
|
|
{
|
|
|
|
|
AppleIIController = new ControllerDefinition { Name = "Apple IIe Keyboard" };
|
|
|
|
|
AppleIIController.BoolButtons.AddRange(RealButtons);
|
|
|
|
|
AppleIIController.BoolButtons.AddRange(ExtraButtons);
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-16 23:24:52 +00:00
|
|
|
|
public AppleII(CoreComm comm, IEnumerable<GameInfo> gameInfoSet, IEnumerable<byte[]> romSet, Settings settings)
|
|
|
|
|
: this(comm, gameInfoSet.First(), romSet.First(), settings)
|
2015-04-12 23:38:19 +00:00
|
|
|
|
{
|
2017-04-24 13:21:05 +00:00
|
|
|
|
_romSet = romSet.ToList();
|
2015-04-12 23:38:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:58:25 +00:00
|
|
|
|
[CoreConstructor("AppleII")]
|
2015-06-16 23:24:52 +00:00
|
|
|
|
public AppleII(CoreComm comm, GameInfo game, byte[] rom, Settings settings)
|
2015-02-17 22:58:25 +00:00
|
|
|
|
{
|
|
|
|
|
var ser = new BasicServiceProvider(this);
|
|
|
|
|
ServiceProvider = ser;
|
|
|
|
|
CoreComm = comm;
|
|
|
|
|
|
2017-04-24 13:21:05 +00:00
|
|
|
|
_tracer = new TraceBuffer
|
2016-02-28 14:15:52 +00:00
|
|
|
|
{
|
2016-08-15 22:39:26 +00:00
|
|
|
|
Header = "6502: PC, opcode, register (A, X, Y, P, SP, Cy), flags (NVTBDIZC)"
|
2016-02-28 14:15:52 +00:00
|
|
|
|
};
|
|
|
|
|
|
2015-02-17 22:58:25 +00:00
|
|
|
|
_disk1 = rom;
|
2017-04-24 13:21:05 +00:00
|
|
|
|
_romSet.Add(rom);
|
2015-02-17 22:58:25 +00:00
|
|
|
|
|
2015-04-09 00:18:01 +00:00
|
|
|
|
_appleIIRom = comm.CoreFileProvider.GetFirmware(
|
|
|
|
|
SystemId, "AppleIIe", true, "The Apple IIe BIOS firmware is required");
|
|
|
|
|
_diskIIRom = comm.CoreFileProvider.GetFirmware(
|
|
|
|
|
SystemId, "DiskII", true, "The DiskII firmware is required");
|
2015-02-18 00:06:49 +00:00
|
|
|
|
|
2015-04-10 00:30:59 +00:00
|
|
|
|
_machine = new Machine(_appleIIRom, _diskIIRom);
|
2015-02-18 00:06:49 +00:00
|
|
|
|
|
|
|
|
|
_machine.BizInitialize();
|
|
|
|
|
|
2017-04-17 20:23:04 +00:00
|
|
|
|
// make a writeable memory stream cloned from the rom.
|
|
|
|
|
// for junk.dsk the .dsk is important because it determines the format from that
|
2015-05-18 00:14:00 +00:00
|
|
|
|
InitDisk();
|
2015-04-13 18:53:36 +00:00
|
|
|
|
|
2017-04-24 13:21:05 +00:00
|
|
|
|
ser.Register<ITraceable>(_tracer);
|
2015-06-21 14:31:18 +00:00
|
|
|
|
|
2017-04-24 13:21:05 +00:00
|
|
|
|
SetCallbacks();
|
2015-07-06 19:15:48 +00:00
|
|
|
|
|
2015-05-18 01:30:30 +00:00
|
|
|
|
InitSaveStates();
|
2015-04-13 18:53:36 +00:00
|
|
|
|
SetupMemoryDomains();
|
2015-06-16 23:24:52 +00:00
|
|
|
|
PutSettings(settings ?? new Settings());
|
2015-02-18 00:06:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-24 13:21:05 +00:00
|
|
|
|
private static readonly ControllerDefinition AppleIIController;
|
2015-04-12 23:38:19 +00:00
|
|
|
|
|
2017-04-24 13:21:05 +00:00
|
|
|
|
private readonly List<byte[]> _romSet = new List<byte[]>();
|
|
|
|
|
private readonly ITraceable _tracer;
|
|
|
|
|
|
|
|
|
|
private Machine _machine;
|
|
|
|
|
private byte[] _disk1;
|
|
|
|
|
private readonly byte[] _appleIIRom;
|
|
|
|
|
private readonly byte[] _diskIIRom;
|
2015-04-13 00:46:11 +00:00
|
|
|
|
|
2017-04-24 13:21:05 +00:00
|
|
|
|
public int CurrentDisk { get; private set; }
|
|
|
|
|
public int DiskCount => _romSet.Count;
|
2015-06-21 14:31:18 +00:00
|
|
|
|
|
2015-04-13 00:46:11 +00:00
|
|
|
|
public void SetDisk(int discNum)
|
|
|
|
|
{
|
|
|
|
|
CurrentDisk = discNum;
|
|
|
|
|
InitDisk();
|
|
|
|
|
}
|
2015-04-12 23:38:19 +00:00
|
|
|
|
|
|
|
|
|
private void IncrementDisk()
|
|
|
|
|
{
|
|
|
|
|
CurrentDisk++;
|
2017-04-24 13:21:05 +00:00
|
|
|
|
if (CurrentDisk >= _romSet.Count)
|
2015-04-12 23:38:19 +00:00
|
|
|
|
{
|
|
|
|
|
CurrentDisk = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InitDisk();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DecrementDisk()
|
|
|
|
|
{
|
|
|
|
|
CurrentDisk--;
|
|
|
|
|
if (CurrentDisk < 0)
|
|
|
|
|
{
|
2017-04-24 13:21:05 +00:00
|
|
|
|
CurrentDisk = _romSet.Count - 1;
|
2015-04-12 23:38:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InitDisk();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void InitDisk()
|
|
|
|
|
{
|
2017-04-24 13:21:05 +00:00
|
|
|
|
_disk1 = _romSet[CurrentDisk];
|
2015-04-12 23:38:19 +00:00
|
|
|
|
|
2017-04-17 20:23:04 +00:00
|
|
|
|
// make a writeable memory stream cloned from the rom.
|
|
|
|
|
// for junk.dsk the .dsk is important because it determines the format from that
|
2015-05-18 00:14:00 +00:00
|
|
|
|
_machine.BootDiskII.Drives[0].InsertDisk("junk.dsk", (byte[])_disk1.Clone(), false);
|
2015-04-12 23:38:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-31 15:02:42 +00:00
|
|
|
|
private static readonly List<string> RealButtons = new List<string>(Keyboard.GetKeyNames()
|
|
|
|
|
.Where(k => k != "White Apple") // Hack because these buttons aren't wired up yet
|
|
|
|
|
.Where(k => k != "Black Apple")
|
|
|
|
|
.Where(k => k != "Reset"));
|
2015-05-18 00:14:00 +00:00
|
|
|
|
|
|
|
|
|
private static readonly List<string> ExtraButtons = new List<string>
|
2015-03-08 03:10:20 +00:00
|
|
|
|
{
|
2015-05-18 00:14:00 +00:00
|
|
|
|
"Previous Disk",
|
|
|
|
|
"Next Disk",
|
|
|
|
|
};
|
2015-03-08 03:10:20 +00:00
|
|
|
|
|
2017-04-24 13:21:05 +00:00
|
|
|
|
public bool DriveLightEnabled => true;
|
|
|
|
|
public bool DriveLightOn => _machine.DriveLight;
|
2015-03-08 03:10:20 +00:00
|
|
|
|
|
2017-04-24 13:21:05 +00:00
|
|
|
|
private bool _nextPressed;
|
|
|
|
|
private bool _prevPressed;
|
2015-06-08 20:56:29 +00:00
|
|
|
|
|
2016-02-21 22:34:14 +00:00
|
|
|
|
private void TracerWrapper(string[] content)
|
|
|
|
|
{
|
2017-04-24 13:21:05 +00:00
|
|
|
|
_tracer.Put(new TraceInfo
|
2016-02-21 22:34:14 +00:00
|
|
|
|
{
|
|
|
|
|
Disassembly = content[0],
|
|
|
|
|
RegisterInfo = content[1]
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-02 01:09:11 +00:00
|
|
|
|
private void FrameAdv(IController controller, bool render, bool rendersound)
|
2015-03-08 03:10:20 +00:00
|
|
|
|
{
|
2017-04-24 13:21:05 +00:00
|
|
|
|
if (_tracer.Enabled)
|
2016-02-21 22:34:14 +00:00
|
|
|
|
{
|
2017-04-24 13:21:05 +00:00
|
|
|
|
_machine.Cpu.TraceCallback = TracerWrapper;
|
2016-02-21 22:34:14 +00:00
|
|
|
|
}
|
2015-06-21 14:31:18 +00:00
|
|
|
|
else
|
2016-02-21 22:34:14 +00:00
|
|
|
|
{
|
2015-06-21 14:31:18 +00:00
|
|
|
|
_machine.Cpu.TraceCallback = null;
|
2016-02-21 22:34:14 +00:00
|
|
|
|
}
|
2015-06-21 14:31:18 +00:00
|
|
|
|
|
2017-05-02 01:09:11 +00:00
|
|
|
|
if (controller.IsPressed("Next Disk") && !_nextPressed)
|
2015-04-12 23:38:19 +00:00
|
|
|
|
{
|
2015-06-08 20:56:29 +00:00
|
|
|
|
_nextPressed = true;
|
2015-04-12 23:38:19 +00:00
|
|
|
|
IncrementDisk();
|
|
|
|
|
}
|
2017-05-02 01:09:11 +00:00
|
|
|
|
else if (controller.IsPressed("Previous Disk") && !_prevPressed)
|
2015-04-12 23:38:19 +00:00
|
|
|
|
{
|
2015-06-08 20:56:29 +00:00
|
|
|
|
_prevPressed = true;
|
2015-04-12 23:38:19 +00:00
|
|
|
|
DecrementDisk();
|
|
|
|
|
}
|
2015-05-18 00:14:00 +00:00
|
|
|
|
|
2017-05-02 01:09:11 +00:00
|
|
|
|
if (!controller.IsPressed("Next Disk"))
|
2015-06-08 20:56:29 +00:00
|
|
|
|
{
|
|
|
|
|
_nextPressed = false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-02 01:09:11 +00:00
|
|
|
|
if (!controller.IsPressed("Previous Disk"))
|
2015-06-08 20:56:29 +00:00
|
|
|
|
{
|
|
|
|
|
_prevPressed = false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-05 16:56:28 +00:00
|
|
|
|
_machine.BizFrameAdvance(RealButtons.Where(controller.IsPressed));
|
2015-04-26 12:40:21 +00:00
|
|
|
|
if (IsLagFrame)
|
|
|
|
|
{
|
|
|
|
|
LagCount++;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-21 21:45:12 +00:00
|
|
|
|
Frame++;
|
2015-03-08 03:10:20 +00:00
|
|
|
|
}
|
2015-07-06 20:09:18 +00:00
|
|
|
|
|
2017-04-24 13:21:05 +00:00
|
|
|
|
private void SetCallbacks()
|
2015-07-06 20:09:18 +00:00
|
|
|
|
{
|
|
|
|
|
_machine.Memory.ReadCallback = MemoryCallbacks.CallReads;
|
|
|
|
|
_machine.Memory.WriteCallback = MemoryCallbacks.CallWrites;
|
|
|
|
|
_machine.Memory.ExecuteCallback = MemoryCallbacks.CallExecutes;
|
|
|
|
|
_machine.Memory.InputCallback = InputCallbacks.Call;
|
|
|
|
|
}
|
2015-02-17 22:58:25 +00:00
|
|
|
|
}
|
|
|
|
|
}
|