ZXHawk: pentagon initialisation
This commit is contained in:
parent
bcd34246ac
commit
1ffeb7cf7e
|
@ -50,17 +50,19 @@ namespace BizHawk.Emulation.Common
|
||||||
FirmwareAndOption("AB16F56989B27D89BABE5F89C5A8CB3DA71A82F0", 16384, "C64", "Drive1541", "drive-1541.bin", "1541 Disk Drive Rom");
|
FirmwareAndOption("AB16F56989B27D89BABE5F89C5A8CB3DA71A82F0", 16384, "C64", "Drive1541", "drive-1541.bin", "1541 Disk Drive Rom");
|
||||||
FirmwareAndOption("D3B78C3DBAC55F5199F33F3FE0036439811F7FB3", 16384, "C64", "Drive1541II", "drive-1541ii.bin", "1541-II Disk Drive Rom");
|
FirmwareAndOption("D3B78C3DBAC55F5199F33F3FE0036439811F7FB3", 16384, "C64", "Drive1541II", "drive-1541ii.bin", "1541-II Disk Drive Rom");
|
||||||
|
|
||||||
// ZX Spectrum
|
// ZX Spectrum
|
||||||
/* These are now shipped with bizhawk
|
/* These are now shipped with bizhawk
|
||||||
FirmwareAndOption("5EA7C2B824672E914525D1D5C419D71B84A426A2", 16384, "ZXSpectrum", "48ROM", "48.ROM", "Spectrum 48K ROM");
|
FirmwareAndOption("5EA7C2B824672E914525D1D5C419D71B84A426A2", 16384, "ZXSpectrum", "48ROM", "48.ROM", "Spectrum 48K ROM");
|
||||||
FirmwareAndOption("16375D42EA109B47EDDED7A16028DE7FDB3013A1", 32768, "ZXSpectrum", "128ROM", "128.ROM", "Spectrum 128K ROM");
|
FirmwareAndOption("16375D42EA109B47EDDED7A16028DE7FDB3013A1", 32768, "ZXSpectrum", "128ROM", "128.ROM", "Spectrum 128K ROM");
|
||||||
FirmwareAndOption("8CAFB292AF58617907B9E6B9093D3588A75849B8", 32768, "ZXSpectrum", "PLUS2ROM", "PLUS2.ROM", "Spectrum 128K +2 ROM");
|
FirmwareAndOption("8CAFB292AF58617907B9E6B9093D3588A75849B8", 32768, "ZXSpectrum", "PLUS2ROM", "PLUS2.ROM", "Spectrum 128K +2 ROM");
|
||||||
FirmwareAndOption("929BF1A5E5687EBD8D7245F9B513A596C0EC21A4", 65536, "ZXSpectrum", "PLUS3ROM", "PLUS3.ROM", "Spectrum 128K +3 ROM");
|
FirmwareAndOption("929BF1A5E5687EBD8D7245F9B513A596C0EC21A4", 65536, "ZXSpectrum", "PLUS3ROM", "PLUS3.ROM", "Spectrum 128K +3 ROM");
|
||||||
*/
|
*/
|
||||||
|
FirmwareAndOption("A584272F21DC82C14B7D4F1ED440E23A976E71F0", 32768, "ZXSpectrum", "PentagonROM", "pentagon.rom", "Russian Pentagon Clone ROM");
|
||||||
|
FirmwareAndOption("282EB7BC819AAD2A12FD954E76F7838A4E1A7929", 16384, "ZXSpectrum", "TRDOSROM", "trdos.rom", "TRDOS ROM");
|
||||||
|
|
||||||
// for saturn, we think any bios region can pretty much run any iso
|
// for saturn, we think any bios region can pretty much run any iso
|
||||||
// so, we're going to lay this out carefully so that we choose things in a sensible order, but prefer the correct region
|
// so, we're going to lay this out carefully so that we choose things in a sensible order, but prefer the correct region
|
||||||
var ss_100_j = File("2B8CB4F87580683EB4D760E4ED210813D667F0A2", 524288, "saturn-1.00-(J).bin", "Bios v1.00 (J)");
|
var ss_100_j = File("2B8CB4F87580683EB4D760E4ED210813D667F0A2", 524288, "saturn-1.00-(J).bin", "Bios v1.00 (J)");
|
||||||
var ss_100_ue = File("FAA8EA183A6D7BBE5D4E03BB1332519800D3FBC3", 524288, "saturn-1.00-(U+E).bin", "Bios v1.00 (U+E)");
|
var ss_100_ue = File("FAA8EA183A6D7BBE5D4E03BB1332519800D3FBC3", 524288, "saturn-1.00-(U+E).bin", "Bios v1.00 (U+E)");
|
||||||
var ss_100a_ue = File("3BB41FEB82838AB9A35601AC666DE5AACFD17A58", 524288, "saturn-1.00a-(U+E).bin", "Bios v1.00a (U+E)"); // ?? is this size correct?
|
var ss_100a_ue = File("3BB41FEB82838AB9A35601AC666DE5AACFD17A58", 524288, "saturn-1.00a-(U+E).bin", "Bios v1.00a (U+E)"); // ?? is this size correct?
|
||||||
var ss_101_j = File("DF94C5B4D47EB3CC404D88B33A8FDA237EAF4720", 524288, "saturn-1.01-(J).bin", "Bios v1.01 (J)"); // ?? is this size correct?
|
var ss_101_j = File("DF94C5B4D47EB3CC404D88B33A8FDA237EAF4720", 524288, "saturn-1.01-(J).bin", "Bios v1.01 (J)"); // ?? is this size correct?
|
||||||
|
|
|
@ -320,6 +320,10 @@
|
||||||
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\AY38912.cs" />
|
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\AY38912.cs" />
|
||||||
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\Beeper.cs" />
|
<Compile Include="Computers\SinclairSpectrum\Hardware\SoundOuput\Beeper.cs" />
|
||||||
<Compile Include="Computers\SinclairSpectrum\Machine\CPUMonitor.cs" />
|
<Compile Include="Computers\SinclairSpectrum\Machine\CPUMonitor.cs" />
|
||||||
|
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.cs" />
|
||||||
|
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Memory.cs" />
|
||||||
|
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Port.cs" />
|
||||||
|
<Compile Include="Computers\SinclairSpectrum\Machine\Pentagon128K\Pentagon128.Screen.cs" />
|
||||||
<Compile Include="Computers\SinclairSpectrum\Machine\ULA.cs" />
|
<Compile Include="Computers\SinclairSpectrum\Machine\ULA.cs" />
|
||||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Screen.cs" />
|
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum128KPlus2a\ZX128Plus2a.Screen.cs" />
|
||||||
<Compile Include="Computers\SinclairSpectrum\Media\Disk\FloppyDisk.cs" />
|
<Compile Include="Computers\SinclairSpectrum\Media\Disk\FloppyDisk.cs" />
|
||||||
|
|
|
@ -34,6 +34,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sinclair Spectrum 128 +3 model
|
/// Sinclair Spectrum 128 +3 model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ZXSpectrum128Plus3
|
ZXSpectrum128Plus3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Russian 128k pentagon clone
|
||||||
|
/// </summary>
|
||||||
|
Pentagon128,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,365 @@
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pentagon 128k Memory
|
||||||
|
/// </summary>
|
||||||
|
public partial class Pentagon128 : SpectrumBase
|
||||||
|
{
|
||||||
|
/* 128k paging controlled by writes to port 0x7ffd
|
||||||
|
*
|
||||||
|
*
|
||||||
|
|
||||||
|
#7FFD (32765) - decoded as A15=0, A1=0 and /IORQ=0. Bits 0..5 are latched. Bits 0..2 select RAM bank in secton D. Bit 3 selects RAM bank to dispay screen (0 - RAM5, 1 - RAM7). Bit 4 selects ROM bank (0 - ROM0, 1 - ROM1). Bit 5, when set locks future writing to #7FFD port until reset. Reading #7FFD port is the same as writing #FF into it.
|
||||||
|
#BFFD (49149) - write data byte into AY-3-8912 chip.
|
||||||
|
#FFFD (65533) - select AY-3-8912 addres (D4..D7 ignored) and reading data byte.
|
||||||
|
|
||||||
|
* 0xffff +--------+--------+--------+--------+--------+--------+--------+--------+
|
||||||
|
| Bank 0 | Bank 1 | Bank 2 | Bank 3 | Bank 4 | Bank 5 | Bank 6 | Bank 7 |
|
||||||
|
| | |(also at| | |(also at| | |
|
||||||
|
| | | 0x8000)| | | 0x4000)| | |
|
||||||
|
| | | | | | screen | | screen |
|
||||||
|
0xc000 +--------+--------+--------+--------+--------+--------+--------+--------+
|
||||||
|
| Bank 2 | Any one of these pages may be switched in.
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
0x8000 +--------+
|
||||||
|
| Bank 5 |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| screen |
|
||||||
|
0x4000 +--------+--------+
|
||||||
|
| ROM 0 | ROM 1 | Either ROM may be switched in.
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
0x0000 +--------+--------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Simulates reading from the bus (no contention)
|
||||||
|
/// 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)
|
||||||
|
{
|
||||||
|
// ROM 0x000
|
||||||
|
case 0:
|
||||||
|
TestForTapeTraps(addr % 0x4000);
|
||||||
|
|
||||||
|
if (ROMPaged == 0)
|
||||||
|
result = ROM0[addr % 0x4000];
|
||||||
|
else
|
||||||
|
result = ROM1[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RAM 0x4000 (RAM5 - Bank5)
|
||||||
|
case 1:
|
||||||
|
result = RAM5[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RAM 0x8000 (RAM2 - Bank2)
|
||||||
|
case 2:
|
||||||
|
result = RAM2[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
|
||||||
|
case 3:
|
||||||
|
switch (RAMPaged)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
result = RAM0[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = RAM1[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = RAM2[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = RAM3[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
result = RAM4[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
result = RAM5[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
result = RAM6[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
result = RAM7[addr % 0x4000];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Simulates writing to the bus (no contention)
|
||||||
|
/// Paging should be handled here
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="addr"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public override void WriteBus(ushort addr, byte value)
|
||||||
|
{
|
||||||
|
int divisor = addr / 0x4000;
|
||||||
|
|
||||||
|
switch (divisor)
|
||||||
|
{
|
||||||
|
// ROM 0x000
|
||||||
|
case 0:
|
||||||
|
// cannot write to ROMs
|
||||||
|
/*
|
||||||
|
if (ROMPaged == 0)
|
||||||
|
ROM0[addr % 0x4000] = value;
|
||||||
|
else
|
||||||
|
ROM1[addr % 0x4000] = value;
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RAM 0x4000 (RAM5 - Bank5 or shadow bank RAM7)
|
||||||
|
case 1:
|
||||||
|
//ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||||
|
RAM5[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RAM 0x8000 (RAM2 - Bank2)
|
||||||
|
case 2:
|
||||||
|
RAM2[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
|
||||||
|
case 3:
|
||||||
|
switch (RAMPaged)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
RAM0[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
RAM1[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
RAM2[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
RAM3[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
RAM4[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
//ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||||
|
RAM5[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
RAM6[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
RAM7[addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a byte of data from a specified memory address
|
||||||
|
/// (with memory contention if appropriate)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="addr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override byte ReadMemory(ushort addr)
|
||||||
|
{
|
||||||
|
var data = ReadBus(addr);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the ROM/RAM enum that relates to this particular memory read operation
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="addr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override ZXSpectrum.CDLResult ReadCDL(ushort addr)
|
||||||
|
{
|
||||||
|
var result = new ZXSpectrum.CDLResult();
|
||||||
|
|
||||||
|
int divisor = addr / 0x4000;
|
||||||
|
result.Address = addr % 0x4000;
|
||||||
|
|
||||||
|
switch (divisor)
|
||||||
|
{
|
||||||
|
// ROM 0x000
|
||||||
|
case 0:
|
||||||
|
if (ROMPaged == 0)
|
||||||
|
result.Type = ZXSpectrum.CDLType.ROM0;
|
||||||
|
else
|
||||||
|
result.Type = ZXSpectrum.CDLType.ROM1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RAM 0x4000 (RAM5 - Bank5)
|
||||||
|
case 1:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RAM 0x8000 (RAM2 - Bank2)
|
||||||
|
case 2:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
|
||||||
|
case 3:
|
||||||
|
switch (RAMPaged)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM3;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM4;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM5;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM6;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
result.Type = ZXSpectrum.CDLType.RAM7;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
/// Checks whether supplied address is in a potentially contended bank
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="addr"></param>
|
||||||
|
public override bool IsContended(ushort addr)
|
||||||
|
{
|
||||||
|
var a = addr & 0xc000;
|
||||||
|
|
||||||
|
if (a == 0x4000)
|
||||||
|
{
|
||||||
|
// low port contention
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a == 0xc000)
|
||||||
|
{
|
||||||
|
// high port contention - check for contended bank paged in
|
||||||
|
switch (RAMPaged)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns TRUE if there is a contended bank paged in
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override bool ContendedBankPaged()
|
||||||
|
{
|
||||||
|
switch (RAMPaged)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ULA reads the memory at the specified address
|
||||||
|
/// (No memory contention)
|
||||||
|
/// Will read RAM5 (screen0) by default, unless RAM7 (screen1) is selected as output
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="addr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override byte FetchScreenMemory(ushort addr)
|
||||||
|
{
|
||||||
|
byte value = new byte();
|
||||||
|
|
||||||
|
if (SHADOWPaged && !PagingDisabled)
|
||||||
|
{
|
||||||
|
// shadow screen should be outputted
|
||||||
|
// this lives in RAM7
|
||||||
|
value = RAM7[addr & 0x3FFF];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// shadow screen is not set to display or paging is disabled (probably in 48k mode)
|
||||||
|
// (use screen0 at RAM5)
|
||||||
|
value = RAM5[addr & 0x3FFF];
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up the ROM
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer"></param>
|
||||||
|
/// <param name="startAddress"></param>
|
||||||
|
public override void InitROM(RomData romData)
|
||||||
|
{
|
||||||
|
RomData = romData;
|
||||||
|
// 128k uses ROM0 and ROM1
|
||||||
|
// 128k loader is in ROM0, and fallback 48k rom is in ROM1
|
||||||
|
for (int i = 0; i < 0x4000; i++)
|
||||||
|
{
|
||||||
|
ROM0[i] = RomData.RomBytes[i];
|
||||||
|
if (RomData.RomBytes.Length > 0x4000)
|
||||||
|
ROM1[i] = RomData.RomBytes[i + 0x4000];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pentagon 128K Port
|
||||||
|
/// </summary>
|
||||||
|
public partial class Pentagon128 : SpectrumBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a byte of data from a specified port address
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="port"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override byte ReadPort(ushort port)
|
||||||
|
{
|
||||||
|
bool deviceAddressed = true;
|
||||||
|
|
||||||
|
int result = 0xFF;
|
||||||
|
|
||||||
|
// ports 0x3ffd & 0x7ffd
|
||||||
|
// traditionally thought to be write-only
|
||||||
|
if (port == 0x3ffd || port == 0x7ffd)
|
||||||
|
{
|
||||||
|
// https://faqwiki.zxnet.co.uk/wiki/ZX_Spectrum_128
|
||||||
|
// HAL bugs
|
||||||
|
// Reads from port 0x7ffd cause a crash, as the 128's HAL10H8 chip does not distinguish between reads and writes to this port,
|
||||||
|
// resulting in a floating data bus being used to set the paging registers.
|
||||||
|
|
||||||
|
// -asni (2018-06-08) - need this to pass the final portread tests from fusetest.tap
|
||||||
|
|
||||||
|
// get the floating bus value
|
||||||
|
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||||
|
// use this to set the paging registers
|
||||||
|
WritePort(port, (byte)result);
|
||||||
|
// return the floating bus value
|
||||||
|
return (byte)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check AY
|
||||||
|
if (AYDevice.ReadPort(port, ref result))
|
||||||
|
return (byte)result;
|
||||||
|
|
||||||
|
byte lowByte = (byte)(port & 0xff);
|
||||||
|
|
||||||
|
// Kempston joystick input takes priority over keyboard input
|
||||||
|
// if this is detected just return the kempston byte
|
||||||
|
if (lowByte == 0x1f)
|
||||||
|
{
|
||||||
|
if (LocateUniqueJoystick(JoystickType.Kempston) != null)
|
||||||
|
return (byte)((KempstonJoystick)LocateUniqueJoystick(JoystickType.Kempston) as KempstonJoystick).JoyLine;
|
||||||
|
|
||||||
|
InputRead = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (KeyboardDevice.ReadPort(port, ref result))
|
||||||
|
{
|
||||||
|
// not a lagframe
|
||||||
|
InputRead = true;
|
||||||
|
|
||||||
|
// process tape INs
|
||||||
|
TapeDevice.ReadPort(port, ref result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
deviceAddressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!deviceAddressed)
|
||||||
|
{
|
||||||
|
// If this is an unused port the floating memory bus should be returned
|
||||||
|
ULADevice.ReadFloatingBus((int)CurrentFrameCycle, ref result, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a byte of data to a specified port address
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="port"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public override void WritePort(ushort port, byte value)
|
||||||
|
{
|
||||||
|
// get a BitArray of the port
|
||||||
|
BitArray portBits = new BitArray(BitConverter.GetBytes(port));
|
||||||
|
// get a BitArray of the value byte
|
||||||
|
BitArray bits = new BitArray(new byte[] { value });
|
||||||
|
|
||||||
|
// handle AY port writes
|
||||||
|
AYDevice.WritePort(port, value);
|
||||||
|
|
||||||
|
// memory paging
|
||||||
|
// this is controlled by writes to port 0x7ffd
|
||||||
|
// but it is only partially decoded so it actually responds to any port with bits 1 and 15 reset
|
||||||
|
if (portBits[1] == false && portBits[15] == false)
|
||||||
|
{
|
||||||
|
Last7ffd = value;
|
||||||
|
|
||||||
|
// if paging is disabled then all writes to this port are ignored until the next reboot
|
||||||
|
if (!PagingDisabled)
|
||||||
|
{
|
||||||
|
// Bits 0, 1, 2 select the RAM page
|
||||||
|
var rp = value & 0x07;
|
||||||
|
if (RAMPaged != rp && rp < 8)
|
||||||
|
RAMPaged = rp;
|
||||||
|
|
||||||
|
// bit 3 controls shadow screen
|
||||||
|
if (SHADOWPaged != bits[3])
|
||||||
|
SHADOWPaged = bits[3];
|
||||||
|
|
||||||
|
// ROM page
|
||||||
|
if (bits[4])
|
||||||
|
{
|
||||||
|
// 48k basic rom
|
||||||
|
ROMPaged = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 128k editor and menu system
|
||||||
|
ROMPaged = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bit 5 set signifies that paging is disabled until next reboot
|
||||||
|
PagingDisabled = bits[5];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no changes to paging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port == 0x1ffd)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the low bit is reset
|
||||||
|
// Technically the ULA should respond to every even I/O address
|
||||||
|
bool lowBitReset = !portBits[0]; // (port & 0x01) == 0;
|
||||||
|
|
||||||
|
// Only even addresses address the ULA
|
||||||
|
if (lowBitReset)
|
||||||
|
{
|
||||||
|
LastFe = value;
|
||||||
|
|
||||||
|
// store the last OUT byte
|
||||||
|
LastULAOutByte = value;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bit 7 6 5 4 3 2 1 0
|
||||||
|
+-------------------------------+
|
||||||
|
| | | | E | M | Border |
|
||||||
|
+-------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Border - LSB 3 bits hold the border colour
|
||||||
|
if (ULADevice.BorderColor != (value & BORDER_BIT))
|
||||||
|
{
|
||||||
|
//ULADevice.RenderScreen((int)CurrentFrameCycle);
|
||||||
|
ULADevice.BorderColor = value & BORDER_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buzzer
|
||||||
|
BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0);
|
||||||
|
TapeDevice.WritePort(port, value);
|
||||||
|
|
||||||
|
// Tape
|
||||||
|
//TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 128K/+2 ULA
|
||||||
|
/// </summary>
|
||||||
|
class ScreenPentagon128 : ULA
|
||||||
|
{
|
||||||
|
#region Construction
|
||||||
|
|
||||||
|
public ScreenPentagon128(SpectrumBase machine)
|
||||||
|
: base(machine)
|
||||||
|
{
|
||||||
|
// interrupt
|
||||||
|
InterruptStartTime = 0;// 3;
|
||||||
|
InterruptLength = 32;
|
||||||
|
// offsets
|
||||||
|
RenderTableOffset = 58;
|
||||||
|
ContentionOffset = 6;
|
||||||
|
FloatingBusOffset = 1;
|
||||||
|
// timing
|
||||||
|
ClockSpeed = 3546900;
|
||||||
|
FrameCycleLength = 71680;
|
||||||
|
ScanlineTime = 224;
|
||||||
|
BorderLeftTime = 24;
|
||||||
|
BorderRightTime = 24;
|
||||||
|
FirstPaperLine = 80;
|
||||||
|
FirstPaperTState = 68;
|
||||||
|
// screen layout
|
||||||
|
Border4T = false;
|
||||||
|
Border4TStage = 1;
|
||||||
|
ScreenWidth = 256;
|
||||||
|
ScreenHeight = 192;
|
||||||
|
BorderTopHeight = 48; // 55; // 48;
|
||||||
|
BorderBottomHeight = 48; // 56;
|
||||||
|
BorderLeftWidth = 48;
|
||||||
|
BorderRightWidth = 48;
|
||||||
|
ScanLineWidth = BorderLeftWidth + ScreenWidth + BorderRightWidth;
|
||||||
|
|
||||||
|
RenderingTable = new RenderTable(this,
|
||||||
|
MachineType.ZXSpectrum128);
|
||||||
|
|
||||||
|
SetupScreenSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 128K Constructor
|
||||||
|
/// </summary>
|
||||||
|
public partial class Pentagon128 : SpectrumBase
|
||||||
|
{
|
||||||
|
#region Construction
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Main constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="spectrum"></param>
|
||||||
|
/// <param name="cpu"></param>
|
||||||
|
public Pentagon128(ZXSpectrum spectrum, Z80A cpu, ZXSpectrum.BorderType borderType, List<byte[]> files, List<JoystickType> joysticks)
|
||||||
|
{
|
||||||
|
Spectrum = spectrum;
|
||||||
|
CPU = cpu;
|
||||||
|
|
||||||
|
CPUMon = new CPUMonitor(this);
|
||||||
|
CPUMon.machineType = MachineType.Pentagon128;
|
||||||
|
|
||||||
|
ROMPaged = 0;
|
||||||
|
SHADOWPaged = false;
|
||||||
|
RAMPaged = 0;
|
||||||
|
PagingDisabled = false;
|
||||||
|
|
||||||
|
ULADevice = new ScreenPentagon128(this);
|
||||||
|
|
||||||
|
BuzzerDevice = new Beeper(this);
|
||||||
|
BuzzerDevice.Init(44100, ULADevice.FrameLength);
|
||||||
|
|
||||||
|
TapeBuzzer = new Beeper(this);
|
||||||
|
TapeBuzzer.Init(44100, ULADevice.FrameLength);
|
||||||
|
|
||||||
|
AYDevice = new AY38912(this);
|
||||||
|
AYDevice.Init(44100, ULADevice.FrameLength);
|
||||||
|
|
||||||
|
KeyboardDevice = new StandardKeyboard(this);
|
||||||
|
|
||||||
|
InitJoysticks(joysticks);
|
||||||
|
|
||||||
|
TapeDevice = new DatacorderDevice(spectrum.SyncSettings.AutoLoadTape);
|
||||||
|
TapeDevice.Init(this);
|
||||||
|
|
||||||
|
InitializeMedia(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -320,7 +320,18 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
|
m.Audio = "Beeper (HW 1ch. / 10oct.) & General Instruments AY-3-8912 PSG (3ch) - RF Output";
|
||||||
m.Media = "3\" Floppy Disk (via built-in Floppy Drive)";
|
m.Media = "3\" Floppy Disk (via built-in Floppy Drive)";
|
||||||
break;
|
break;
|
||||||
}
|
case MachineType.Pentagon128:
|
||||||
|
m.Name = "(NOT WORKING YET) Pentagon 128 Clone";
|
||||||
|
m.Description = " ";
|
||||||
|
m.Description += " ";
|
||||||
|
m.Released = " ";
|
||||||
|
m.CPU = " ";
|
||||||
|
m.Memory = " ";
|
||||||
|
m.Video = " ";
|
||||||
|
m.Audio = " ";
|
||||||
|
m.Media = " ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Name), m.Name.Trim());
|
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Name), m.Name.Trim());
|
||||||
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Description), m.Description.Trim());
|
m.Data.Add(ZXSpectrum.GetMemberName((ZXMachineMetaData c) => c.Description), m.Description.Trim());
|
||||||
|
|
|
@ -90,6 +90,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
ControllerDefinition = ZXSpectrumControllerDefinition;
|
ControllerDefinition = ZXSpectrumControllerDefinition;
|
||||||
Init(MachineType.ZXSpectrum128Plus3, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
|
Init(MachineType.ZXSpectrum128Plus3, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
|
||||||
break;
|
break;
|
||||||
|
case MachineType.Pentagon128:
|
||||||
|
ControllerDefinition = ZXSpectrumControllerDefinition;
|
||||||
|
Init(MachineType.Pentagon128, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _files, joysticks);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException("Machine not yet emulated");
|
throw new InvalidOperationException("Machine not yet emulated");
|
||||||
}
|
}
|
||||||
|
@ -264,6 +268,14 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
_machine.InitROM(romDataP3);
|
_machine.InitROM(romDataP3);
|
||||||
//System.Windows.Forms.MessageBox.Show("+3 is not working at all yet :/");
|
//System.Windows.Forms.MessageBox.Show("+3 is not working at all yet :/");
|
||||||
break;
|
break;
|
||||||
|
case MachineType.Pentagon128:
|
||||||
|
_machine = new Pentagon128(this, _cpu, borderType, files, joys);
|
||||||
|
var _systemRomPen128 = GetFirmware(0x8000, "PentagonROM");
|
||||||
|
var _systemRomTrdos = GetFirmware(0x4000, "TRDOSROM");
|
||||||
|
var conc = _systemRomPen128.Concat(_systemRomTrdos).ToArray();
|
||||||
|
var romDataPen128 = RomData.InitROM(machineType, conc);
|
||||||
|
_machine.InitROM(romDataPen128);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue