CPCHawk: Fixed ROM & RAM banking. Started CPC6128 implementation.
This commit is contained in:
parent
ac0aae4afb
commit
facbdd3630
|
@ -158,6 +158,9 @@
|
|||
<Compile Include="Computers\AmstradCPC\Machine\CPC464\CPC464.cs" />
|
||||
<Compile Include="Computers\AmstradCPC\Machine\CPC464\CPC464.Memory.cs" />
|
||||
<Compile Include="Computers\AmstradCPC\Machine\CPC464\CPC464.Port.cs" />
|
||||
<Compile Include="Computers\AmstradCPC\Machine\CPC6128\CPC6128.Port.cs" />
|
||||
<Compile Include="Computers\AmstradCPC\Machine\CPC6128\CPC6128.Memory.cs" />
|
||||
<Compile Include="Computers\AmstradCPC\Machine\CPC6128\CPC6128.cs" />
|
||||
<Compile Include="Computers\AmstradCPC\Machine\CPCBase.cs" />
|
||||
<Compile Include="Computers\AmstradCPC\Machine\CPCBase.Input.cs" />
|
||||
<Compile Include="Computers\AmstradCPC\Machine\CPCBase.Media.cs" />
|
||||
|
@ -1501,8 +1504,12 @@
|
|||
<None Include="Resources\128.ROM.gz" />
|
||||
<None Include="Resources\48.ROM.gz" />
|
||||
<None Include="Resources\cgb_boot.bin.gz" />
|
||||
<None Include="Resources\cpc464.rom.gz" />
|
||||
<None Include="Resources\CPC_AMSDOS_0.5.ROM.gz" />
|
||||
<None Include="Resources\CPC_BASIC_1.0.ROM.gz" />
|
||||
<None Include="Resources\CPC_BASIC_1.1.ROM.gz" />
|
||||
<None Include="Resources\CPC_OS_6128.ROM.gz" />
|
||||
<None Include="Resources\dmg_boot.bin.gz" />
|
||||
<None Include="Resources\OS_464.ROM.gz" />
|
||||
<None Include="Resources\plus2.rom.gz" />
|
||||
<None Include="Resources\plus2a.rom.gz" />
|
||||
<None Include="Resources\sgb-cart-present.spc.gz" />
|
||||
|
|
|
@ -34,7 +34,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
_machine.WriteBus((ushort)addr, value);
|
||||
}, 1)
|
||||
};
|
||||
|
@ -48,18 +47,22 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
|
||||
private void SyncAllByteArrayDomains()
|
||||
{
|
||||
{
|
||||
SyncByteArrayDomain("ROMLower", _machine.ROMLower);
|
||||
SyncByteArrayDomain("ROM0", _machine.ROM0);
|
||||
SyncByteArrayDomain("ROM1", _machine.ROM1);
|
||||
SyncByteArrayDomain("ROM7", _machine.ROM7);
|
||||
SyncByteArrayDomain("RAM0", _machine.RAM0);
|
||||
SyncByteArrayDomain("RAM1", _machine.RAM1);
|
||||
SyncByteArrayDomain("RAM2", _machine.RAM2);
|
||||
SyncByteArrayDomain("RAM3", _machine.RAM3);
|
||||
SyncByteArrayDomain("RAM3", _machine.RAM3);
|
||||
SyncByteArrayDomain("RAM4", _machine.RAM4);
|
||||
SyncByteArrayDomain("RAM5", _machine.RAM5);
|
||||
SyncByteArrayDomain("RAM6", _machine.RAM6);
|
||||
SyncByteArrayDomain("RAM7", _machine.RAM7);
|
||||
}
|
||||
|
||||
private void SyncByteArrayDomain(string name, byte[] data)
|
||||
{
|
||||
|
||||
{
|
||||
if (_memoryDomainsInit || _byteArrayDomains.ContainsKey(name))
|
||||
{
|
||||
var m = _byteArrayDomains[name];
|
||||
|
@ -69,8 +72,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
{
|
||||
var m = new MemoryDomainByteArray(name, MemoryDomain.Endian.Little, data, true, 1);
|
||||
_byteArrayDomains.Add(name, m);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,8 +120,23 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
bool embeddedFound = true;
|
||||
switch (names.FirstOrDefault())
|
||||
{
|
||||
case "464ROM":
|
||||
embeddedRom = Util.DecompressGzipFile(new MemoryStream(Resources.cpc464_rom));
|
||||
// CPC 464 ROMS
|
||||
case "OS464ROM":
|
||||
embeddedRom = Util.DecompressGzipFile(new MemoryStream(Resources.OS_464_ROM));
|
||||
break;
|
||||
case "BASIC1-0ROM":
|
||||
embeddedRom = Util.DecompressGzipFile(new MemoryStream(Resources.CPC_BASIC_1_0_ROM));
|
||||
break;
|
||||
|
||||
// CPC 6128 ROMS
|
||||
case "OS6128ROM":
|
||||
embeddedRom = Util.DecompressGzipFile(new MemoryStream(Resources.CPC_OS_6128_ROM));
|
||||
break;
|
||||
case "BASIC1-1ROM":
|
||||
embeddedRom = Util.DecompressGzipFile(new MemoryStream(Resources.CPC_BASIC_1_1_ROM));
|
||||
break;
|
||||
case "AMSDOS0-5ROM":
|
||||
embeddedRom = Util.DecompressGzipFile(new MemoryStream(Resources.CPC_AMSDOS_0_5_ROM));
|
||||
break;
|
||||
default:
|
||||
embeddedFound = false;
|
||||
|
@ -152,9 +167,19 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
{
|
||||
case MachineType.CPC464:
|
||||
_machine = new CPC464(this, _cpu, files, autoTape);
|
||||
var _systemRom16 = GetFirmware(0x4000, "464ROM");
|
||||
var romData16 = RomData.InitROM(machineType, _systemRom16);
|
||||
_machine.InitROM(romData16);
|
||||
List<RomData> roms64 = new List<RomData>();
|
||||
roms64.Add(RomData.InitROM(MachineType.CPC464, GetFirmware(0x4000, "OS464ROM"), RomData.ROMChipType.Lower));
|
||||
roms64.Add(RomData.InitROM(MachineType.CPC464, GetFirmware(0x4000, "BASIC1-0ROM"), RomData.ROMChipType.Upper, 0));
|
||||
_machine.InitROM(roms64.ToArray());
|
||||
break;
|
||||
|
||||
case MachineType.CPC6128:
|
||||
_machine = new CPC6128(this, _cpu, files, autoTape);
|
||||
List<RomData> roms128 = new List<RomData>();
|
||||
roms128.Add(RomData.InitROM(MachineType.CPC6128, GetFirmware(0x4000, "OS6128ROM"), RomData.ROMChipType.Lower));
|
||||
roms128.Add(RomData.InitROM(MachineType.CPC6128, GetFirmware(0x4000, "BASIC1-1ROM"), RomData.ROMChipType.Upper, 0));
|
||||
roms128.Add(RomData.InitROM(MachineType.CPC6128, GetFirmware(0x4000, "AMSDOS0-5ROM"), RomData.ROMChipType.Upper, 7));
|
||||
_machine.InitROM(roms128.ToArray());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
// 0x000 or LowerROM
|
||||
case 0:
|
||||
if (LowerROMPaged)
|
||||
result = ROM0[addr % 0x4000];
|
||||
result = ROMLower[addr % 0x4000];
|
||||
else
|
||||
result = RAM0[addr % 0x4000];
|
||||
break;
|
||||
|
@ -46,7 +46,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
// 0xc000 or UpperROM
|
||||
case 3:
|
||||
if (UpperROMPaged)
|
||||
result = ROM1[addr % 0x4000];
|
||||
result = ROM0[addr % 0x4000];
|
||||
else
|
||||
result = RAM3[addr % 0x4000];
|
||||
break;
|
||||
|
@ -121,14 +121,33 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="startAddress"></param>
|
||||
public override void InitROM(RomData romData)
|
||||
public override void InitROM(RomData[] romData)
|
||||
{
|
||||
RomData = romData;
|
||||
for (int i = 0; i < 0x4000; i++)
|
||||
foreach (var r in romData)
|
||||
{
|
||||
ROM0[i] = RomData.RomBytes[i];
|
||||
if (RomData.RomBytes.Length > 0x4000)
|
||||
ROM1[i] = RomData.RomBytes[i + 0x4000];
|
||||
if (r.ROMType == RomData.ROMChipType.Lower)
|
||||
{
|
||||
for (int i = 0; i < 0x4000; i++)
|
||||
{
|
||||
ROMLower[i] = r.RomBytes[i];
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 0x4000; i++)
|
||||
{
|
||||
switch (r.ROMPosition)
|
||||
{
|
||||
case 0:
|
||||
ROM0[i] = r.RomBytes[i];
|
||||
break;
|
||||
case 7:
|
||||
ROM7[i] = r.RomBytes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LowerROMPaged = true;
|
||||
|
|
|
@ -29,10 +29,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
if (DecodeINPort(port) == PortDevice.GateArray)
|
||||
{
|
||||
GateArray.ReadPort(port, ref result);
|
||||
}
|
||||
else if (DecodeINPort(port) == PortDevice.RAMManagement)
|
||||
{
|
||||
|
||||
}
|
||||
else if (DecodeINPort(port) == PortDevice.CRCT)
|
||||
{
|
||||
|
@ -81,7 +77,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
}
|
||||
else if (d == PortDevice.RAMManagement)
|
||||
{
|
||||
|
||||
// not present in the unexpanded CPC464
|
||||
}
|
||||
else if (d == PortDevice.CRCT)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||
{
|
||||
/// <summary>
|
||||
/// CPC6128
|
||||
/// * Memory *
|
||||
/// </summary>
|
||||
public partial class CPC6128 : CPCBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Simulates reading from the bus
|
||||
/// ROM and RAM paging should be handled here
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <returns></returns>
|
||||
public override byte ReadBus(ushort addr)
|
||||
{
|
||||
int divisor = addr / 0x4000;
|
||||
byte result = 0xff;
|
||||
|
||||
switch (divisor)
|
||||
{
|
||||
// RAM 0x000
|
||||
case 0:
|
||||
if (LowerROMPaged)
|
||||
{
|
||||
result = ROMLower[addr % 0x4000];
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (RAMConfig)
|
||||
{
|
||||
case 2:
|
||||
result = RAM4[addr % 0x4000];
|
||||
break;
|
||||
default:
|
||||
result = RAM0[addr % 0x4000];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// RAM 0x4000
|
||||
case 1:
|
||||
switch (RAMConfig)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
result = RAM1[addr % 0x4000];
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
result = RAM5[addr % 0x4000];
|
||||
break;
|
||||
case 3:
|
||||
result = RAM3[addr % 0x4000];
|
||||
break;
|
||||
case 4:
|
||||
result = RAM4[addr % 0x4000];
|
||||
break;
|
||||
case 6:
|
||||
result = RAM6[addr % 0x4000];
|
||||
break;
|
||||
case 7:
|
||||
result = RAM7[addr % 0x4000];
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// RAM 0x8000
|
||||
case 2:
|
||||
switch (RAMConfig)
|
||||
{
|
||||
case 2:
|
||||
result = RAM6[addr % 0x4000];
|
||||
break;
|
||||
default:
|
||||
result = RAM2[addr % 0x4000];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// RAM 0xc000
|
||||
case 3:
|
||||
if (UpperROMPaged)
|
||||
{
|
||||
switch (UpperROMPosition)
|
||||
{
|
||||
case 7:
|
||||
result = ROM7[addr % 0x4000];
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
result = ROM0[addr % 0x4000];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (RAMConfig)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
result = RAM7[addr % 0x4000];
|
||||
break;
|
||||
default:
|
||||
result = RAM3[addr % 0x4000];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simulates writing to the bus
|
||||
/// Writes to the bus ALWAYS go to RAM, regardless of what upper and lower ROMs are paged in
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <param name="value"></param>
|
||||
public override void WriteBus(ushort addr, byte value)
|
||||
{
|
||||
int divisor = addr / 0x4000;
|
||||
|
||||
switch (divisor)
|
||||
{
|
||||
// RAM 0x000
|
||||
case 0:
|
||||
switch (RAMConfig)
|
||||
{
|
||||
case 2:
|
||||
RAM4[addr % 0x4000] = value;
|
||||
break;
|
||||
default:
|
||||
RAM0[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// RAM 0x4000
|
||||
case 1:
|
||||
switch (RAMConfig)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
RAM1[addr % 0x4000] = value;
|
||||
break;
|
||||
case 2:
|
||||
case 5:
|
||||
RAM5[addr % 0x4000] = value;
|
||||
break;
|
||||
case 3:
|
||||
RAM3[addr % 0x4000] = value;
|
||||
break;
|
||||
case 4:
|
||||
RAM4[addr % 0x4000] = value;
|
||||
break;
|
||||
case 6:
|
||||
RAM6[addr % 0x4000] = value;
|
||||
break;
|
||||
case 7:
|
||||
RAM7[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// RAM 0x8000
|
||||
case 2:
|
||||
switch (RAMConfig)
|
||||
{
|
||||
case 2:
|
||||
RAM6[addr % 0x4000] = value;
|
||||
break;
|
||||
default:
|
||||
RAM2[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// RAM 0xc000
|
||||
case 3:
|
||||
switch (RAMConfig)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
RAM7[addr % 0x4000] = value;
|
||||
break;
|
||||
default:
|
||||
RAM3[addr % 0x4000] = value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a byte of data from a specified memory address
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <returns></returns>
|
||||
public override byte ReadMemory(ushort addr)
|
||||
{
|
||||
var data = ReadBus(addr);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a byte of data to a specified memory address
|
||||
/// (with memory contention if appropriate)
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <param name="value"></param>
|
||||
public override void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
WriteBus(addr, value);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the ROM
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="startAddress"></param>
|
||||
public override void InitROM(RomData[] romData)
|
||||
{
|
||||
foreach (var r in romData)
|
||||
{
|
||||
if (r.ROMType == RomData.ROMChipType.Lower)
|
||||
{
|
||||
for (int i = 0; i < 0x4000; i++)
|
||||
{
|
||||
ROMLower[i] = r.RomBytes[i];
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 0x4000; i++)
|
||||
{
|
||||
switch (r.ROMPosition)
|
||||
{
|
||||
case 0:
|
||||
ROM0[i] = r.RomBytes[i];
|
||||
break;
|
||||
case 7:
|
||||
ROM7[i] = r.RomBytes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LowerROMPaged = true;
|
||||
UpperROMPaged = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
using BizHawk.Common.NumberExtensions;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||
{
|
||||
/// <summary>
|
||||
/// CPC6128
|
||||
/// * Port *
|
||||
/// </summary>
|
||||
public partial class CPC6128 : CPCBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads a byte of data from a specified port address
|
||||
/// </summary>
|
||||
/// <param name="port"></param>
|
||||
/// <returns></returns>
|
||||
public override byte ReadPort(ushort port)
|
||||
{
|
||||
BitArray portBits = new BitArray(BitConverter.GetBytes(port));
|
||||
byte portUpper = (byte)(port >> 8);
|
||||
byte portLower = (byte)(port & 0xff);
|
||||
|
||||
int result = 0xff;
|
||||
|
||||
if (DecodeINPort(port) == PortDevice.GateArray)
|
||||
{
|
||||
GateArray.ReadPort(port, ref result);
|
||||
}
|
||||
else if (DecodeINPort(port) == PortDevice.CRCT)
|
||||
{
|
||||
CRCT.ReadPort(port, ref result);
|
||||
}
|
||||
else if (DecodeINPort(port) == PortDevice.ROMSelect)
|
||||
{
|
||||
|
||||
}
|
||||
else if (DecodeINPort(port) == PortDevice.Printer)
|
||||
{
|
||||
|
||||
}
|
||||
else if (DecodeINPort(port) == PortDevice.PPI)
|
||||
{
|
||||
PPI.ReadPort(port, ref result);
|
||||
}
|
||||
else if (DecodeINPort(port) == PortDevice.Expansion)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return (byte)result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a byte of data to a specified port address
|
||||
/// Because of the port decoding, multiple devices can be written to
|
||||
/// </summary>
|
||||
/// <param name="port"></param>
|
||||
/// <param name="value"></param>
|
||||
public override void WritePort(ushort port, byte value)
|
||||
{
|
||||
BitArray portBits = new BitArray(BitConverter.GetBytes(port));
|
||||
BitArray dataBits = new BitArray(BitConverter.GetBytes(value));
|
||||
byte portUpper = (byte)(port >> 8);
|
||||
byte portLower = (byte)(port & 0xff);
|
||||
|
||||
var devs = DecodeOUTPort(port);
|
||||
|
||||
foreach (var d in devs)
|
||||
{
|
||||
if (d == PortDevice.GateArray)
|
||||
{
|
||||
GateArray.WritePort(port, value);
|
||||
}
|
||||
else if (d == PortDevice.RAMManagement)
|
||||
{
|
||||
if (value.Bit(7) && value.Bit(6))
|
||||
{
|
||||
RAMConfig = value & 0x07;
|
||||
|
||||
// additional 64K bank index
|
||||
var b64 = value & 0x38;
|
||||
}
|
||||
}
|
||||
else if (d == PortDevice.CRCT)
|
||||
{
|
||||
CRCT.WritePort(port, value);
|
||||
}
|
||||
else if (d == PortDevice.ROMSelect)
|
||||
{
|
||||
UpperROMPosition = value;
|
||||
}
|
||||
else if (d == PortDevice.Printer)
|
||||
{
|
||||
|
||||
}
|
||||
else if (d == PortDevice.PPI)
|
||||
{
|
||||
PPI.WritePort(port, value);
|
||||
}
|
||||
else if (d == PortDevice.Expansion)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||
{
|
||||
/// <summary>
|
||||
/// CPC6128 construction
|
||||
/// </summary>
|
||||
public partial class CPC6128 : CPCBase
|
||||
{
|
||||
#region Construction
|
||||
|
||||
/// <summary>
|
||||
/// Main constructor
|
||||
/// </summary>
|
||||
/// <param name="spectrum"></param>
|
||||
/// <param name="cpu"></param>
|
||||
public CPC6128(AmstradCPC cpc, Z80A cpu, List<byte[]> files, bool autoTape)
|
||||
{
|
||||
CPC = cpc;
|
||||
CPU = cpu;
|
||||
|
||||
FrameLength = 79872;
|
||||
|
||||
CRCT = new CRCT_6845(CRCT_6845.CRCTType.Motorola_MC6845, this);
|
||||
CRT = new CRTDevice(this);
|
||||
GateArray = new AmstradGateArray(this, AmstradGateArray.GateArrayType.Amstrad40007);
|
||||
PPI = new PPI_8255(this);
|
||||
|
||||
TapeBuzzer = new Beeper(this);
|
||||
TapeBuzzer.Init(44100, FrameLength);
|
||||
|
||||
//AYDevice = new PSG(this, PSG.ay38910_type_t.AY38910_TYPE_8912, GateArray.PSGClockSpeed, 882 * 50);
|
||||
AYDevice = new AY38912(this);
|
||||
AYDevice.Init(44100, FrameLength);
|
||||
|
||||
KeyboardDevice = new StandardKeyboard(this);
|
||||
|
||||
TapeDevice = new DatacorderDevice(autoTape);
|
||||
TapeDevice.Init(this);
|
||||
|
||||
UPDDiskDevice = new NECUPD765();
|
||||
UPDDiskDevice.Init(this);
|
||||
|
||||
InitializeMedia(files);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||
{
|
||||
|
@ -10,30 +11,61 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
{
|
||||
#region Memory Fields & Properties
|
||||
|
||||
/* ROM Banks */
|
||||
/// <summary>
|
||||
/// ROM Banks
|
||||
/// </summary>
|
||||
public byte[] ROM0 = new byte[0x4000];
|
||||
public byte[] ROM1 = new byte[0x4000];
|
||||
|
||||
/// <summary>
|
||||
/// RAM Banks
|
||||
/// Lower: OS ROM
|
||||
/// </summary>
|
||||
public byte[] RAM0 = new byte[0x4000]; // Bank 0
|
||||
public byte[] RAM1 = new byte[0x4000]; // Bank 1
|
||||
public byte[] RAM2 = new byte[0x4000]; // Bank 2
|
||||
public byte[] RAM3 = new byte[0x4000]; // Bank 3
|
||||
public byte[] ROMLower = new byte[0x4000];
|
||||
/// <summary>
|
||||
/// Upper: POS 0 (usually BASIC)
|
||||
/// </summary>
|
||||
public byte[] ROM0 = new byte[0x4000];
|
||||
/// <summary>
|
||||
/// Upper: POS 7 (usually AMSDOS)
|
||||
/// </summary>
|
||||
public byte[] ROM7 = new byte[0x4000];
|
||||
|
||||
/* RAM Banks - Lower 64K */
|
||||
public byte[] RAM0 = new byte[0x4000];
|
||||
public byte[] RAM1 = new byte[0x4000];
|
||||
public byte[] RAM2 = new byte[0x4000];
|
||||
public byte[] RAM3 = new byte[0x4000];
|
||||
|
||||
/* RAM Banks - Upper 64K */
|
||||
public byte[] RAM4 = new byte[0x4000];
|
||||
public byte[] RAM5 = new byte[0x4000];
|
||||
public byte[] RAM6 = new byte[0x4000];
|
||||
public byte[] RAM7 = new byte[0x4000];
|
||||
|
||||
/// <summary>
|
||||
/// Signs whether Upper ROM is paged in
|
||||
/// </summary>
|
||||
public bool UpperROMPaged;
|
||||
|
||||
/// <summary>
|
||||
/// The position of the currently paged upper ROM
|
||||
/// </summary>
|
||||
public int UpperROMPosition;
|
||||
|
||||
/// <summary>
|
||||
/// Signs whether Lower ROM is paged in
|
||||
/// </summary>
|
||||
public bool LowerROMPaged;
|
||||
|
||||
/// <summary>
|
||||
/// The currently selected RAM config
|
||||
/// </summary>
|
||||
public int RAMConfig;
|
||||
|
||||
/// <summary>
|
||||
/// Always 0 on a CPC6128
|
||||
/// On a machine with more than 128K RAM (standard memory expansion) this selects each additional 64K above the first upper 64K
|
||||
/// </summary>
|
||||
public int RAM64KBank;
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Memory Related Methods
|
||||
|
@ -84,7 +116,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
/// Sets up the ROM
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
public abstract void InitROM(RomData romData);
|
||||
public abstract void InitROM(RomData[] romData);
|
||||
|
||||
/// <summary>
|
||||
/// ULA reads the memory at the specified address
|
||||
|
|
|
@ -328,12 +328,23 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
ser.Sync("_frameCycles", ref _frameCycles);
|
||||
ser.Sync("inputRead", ref inputRead);
|
||||
ser.Sync("LastFrameStartCPUTick", ref LastFrameStartCPUTick);
|
||||
ser.Sync("ROMLower", ref ROMLower, false);
|
||||
ser.Sync("ROM0", ref ROM0, false);
|
||||
ser.Sync("ROM1", ref ROM1, false);
|
||||
ser.Sync("ROM7", ref ROM7, false);
|
||||
ser.Sync("RAM0", ref RAM0, false);
|
||||
ser.Sync("RAM1", ref RAM1, false);
|
||||
ser.Sync("RAM2", ref RAM2, false);
|
||||
ser.Sync("RAM3", ref RAM3, false);
|
||||
ser.Sync("RAM4", ref RAM4, false);
|
||||
ser.Sync("RAM5", ref RAM5, false);
|
||||
ser.Sync("RAM6", ref RAM6, false);
|
||||
ser.Sync("RAM7", ref RAM7, false);
|
||||
|
||||
ser.Sync("UpperROMPosition", ref UpperROMPosition);
|
||||
ser.Sync("UpperROMPaged", ref UpperROMPaged);
|
||||
ser.Sync("LowerROMPaged", ref LowerROMPaged);
|
||||
ser.Sync("RAMConfig", ref RAMConfig);
|
||||
ser.Sync("RAM64KBank", ref RAM64KBank);
|
||||
|
||||
CRCT.SyncState(ser);
|
||||
CRT.SyncState(ser);
|
||||
|
|
|
@ -14,58 +14,52 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
|||
get { return _romBytes; }
|
||||
set { _romBytes = value; }
|
||||
}
|
||||
private byte[] _romBytes;
|
||||
|
||||
public enum ROMChipType
|
||||
{
|
||||
Lower,
|
||||
Upper
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Useful ROM addresses that are needed during tape operations
|
||||
/// Whether this is an Upper or Lower ROM
|
||||
/// </summary>
|
||||
public ushort SaveBytesRoutineAddress
|
||||
{
|
||||
get { return _saveBytesRoutineAddress; }
|
||||
set { _saveBytesRoutineAddress = value; }
|
||||
}
|
||||
public ushort LoadBytesRoutineAddress
|
||||
{
|
||||
get { return _loadBytesRoutineAddress; }
|
||||
set { _loadBytesRoutineAddress = value; }
|
||||
}
|
||||
public ushort SaveBytesResumeAddress
|
||||
{
|
||||
get { return _saveBytesResumeAddress; }
|
||||
set { _saveBytesResumeAddress = value; }
|
||||
}
|
||||
public ushort LoadBytesResumeAddress
|
||||
{
|
||||
get { return _loadBytesResumeAddress; }
|
||||
set { _loadBytesResumeAddress = value; }
|
||||
}
|
||||
public ushort LoadBytesInvalidHeaderAddress
|
||||
{
|
||||
get { return _loadBytesInvalidHeaderAddress; }
|
||||
set { _loadBytesInvalidHeaderAddress = value; }
|
||||
}
|
||||
public ROMChipType ROMType;
|
||||
|
||||
private byte[] _romBytes;
|
||||
private ushort _saveBytesRoutineAddress;
|
||||
private ushort _loadBytesRoutineAddress;
|
||||
private ushort _saveBytesResumeAddress;
|
||||
private ushort _loadBytesResumeAddress;
|
||||
private ushort _loadBytesInvalidHeaderAddress;
|
||||
/// <summary>
|
||||
/// The designated ROM position for this ROM
|
||||
/// </summary>
|
||||
public int ROMPosition;
|
||||
|
||||
|
||||
public static RomData InitROM(MachineType machineType, byte[] rom)
|
||||
/// <summary>
|
||||
/// Initialise a RomData object
|
||||
/// </summary>
|
||||
/// <param name="machineType"></param>
|
||||
/// <param name="rom"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="romPosition"></param>
|
||||
/// <returns></returns>
|
||||
public static RomData InitROM(MachineType machineType, byte[] rom, ROMChipType type, int romPosition = 0)
|
||||
{
|
||||
RomData RD = new RomData();
|
||||
RD.RomBytes = new byte[rom.Length];
|
||||
RD.RomBytes = rom;
|
||||
RD.ROMType = type;
|
||||
|
||||
if (type == ROMChipType.Upper)
|
||||
{
|
||||
RD.ROMPosition = romPosition;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rom.Length; i++)
|
||||
RD.RomBytes[i] = rom[i];
|
||||
|
||||
switch (machineType)
|
||||
{
|
||||
case MachineType.CPC464:
|
||||
RD.SaveBytesRoutineAddress = 0x04C2;
|
||||
RD.SaveBytesResumeAddress = 0x0000;
|
||||
RD.LoadBytesRoutineAddress = 0x0808; //0x0556; //0x056C;
|
||||
RD.LoadBytesResumeAddress = 0x05E2;
|
||||
RD.LoadBytesInvalidHeaderAddress = 0x05B6;
|
||||
break;
|
||||
case MachineType.CPC6128:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,9 +63,49 @@ namespace BizHawk.Emulation.Cores.Properties {
|
|||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] cpc464_rom {
|
||||
internal static byte[] CPC_AMSDOS_0_5_ROM {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("cpc464_rom", resourceCulture);
|
||||
object obj = ResourceManager.GetObject("CPC_AMSDOS_0_5_ROM", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] CPC_BASIC_1_0_ROM {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("CPC_BASIC_1_0_ROM", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] CPC_BASIC_1_1_ROM {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("CPC_BASIC_1_1_ROM", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] CPC_OS_6128_ROM {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("CPC_OS_6128_ROM", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] OS_464_ROM {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("OS_464_ROM", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,19 @@
|
|||
<data name="ZX_plus2_rom" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\plus2.rom.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="cpc464_rom" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\cpc464.rom.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<data name="CPC_AMSDOS_0_5_ROM" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\CPC_AMSDOS_0.5.ROM.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="CPC_BASIC_1_0_ROM" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\CPC_BASIC_1.0.ROM.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="CPC_BASIC_1_1_ROM" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\CPC_BASIC_1.1.ROM.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="CPC_OS_6128_ROM" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\CPC_OS_6128.ROM.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="OS_464_ROM" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\OS_464.ROM.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
</root>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue