diff --git a/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs b/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs
index 9d9810b5e6..7755353463 100644
--- a/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs
+++ b/BizHawk.Emulation.Common/Database/FirmwareDatabase.cs
@@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Common
FirmwareAndOption("5EA7C2B824672E914525D1D5C419D71B84A426A2", 16384, "ZXSpectrum", "48ROM", "48.ROM", "Spectrum 48K ROM");
FirmwareAndOption("16375D42EA109B47EDDED7A16028DE7FDB3013A1", 32768, "ZXSpectrum", "128ROM", "128.ROM", "Spectrum 128K ROM");
FirmwareAndOption("8CAFB292AF58617907B9E6B9093D3588A75849B8", 32768, "ZXSpectrum", "PLUS2ROM", "PLUS2.ROM", "Spectrum 128K +2 ROM");
- FirmwareAndOption("929BF1A5E5687EBD8D7245F9B513A596C0EC21A4", 65563, "ZXSpectrum", "PLUS3ROM", "PLUS3.ROM", "Spectrum 128K +3 ROM");
+ FirmwareAndOption("929BF1A5E5687EBD8D7245F9B513A596C0EC21A4", 65536, "ZXSpectrum", "PLUS3ROM", "PLUS3.ROM", "Spectrum 128K +3 ROM");
// 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
diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index 274f62c6a4..70231ad7e7 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -1391,6 +1391,7 @@
+
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/MachineType.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/MachineType.cs
index a29b745205..cb895cf171 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/MachineType.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/MachineType.cs
@@ -19,8 +19,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
ZXSpectrum128,
///
- /// Sinclair Spectrum 128 + 2 model
+ /// Sinclair Spectrum 128 +2 model
///
- ZXSpectrum128Plus2
+ ZXSpectrum128Plus2,
+
+ ///
+ /// Sinclair Spectrum 128 +3 model
+ ///
+ ZXSpectrum128Plus3
}
}
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Screen.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Screen.cs
index 3ab09352db..69bdc62382 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Screen.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Screen.cs
@@ -913,13 +913,44 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
*/
public int[] GetVideoBuffer()
{
- return _frameBuffer;
+ /*
+ switch(Spectrum.SyncSettings.BorderType)
+ {
+ case ZXSpectrum.BorderType.Full:
+ return _frameBuffer;
- // convert the generated _framebuffer into ARGB colours via the ULAPalette
- int[] trans = new int[_frameBuffer.Length];
- for (int i = 0; i < _frameBuffer.Length; i++)
- trans[i] = ULAPalette[_frameBuffer[i]];
- return trans; //_frameBuffer;
+ case ZXSpectrum.BorderType.Small:
+ // leave only 10 border units all around
+ int[] smlBuff = new int[(ScreenWidth - 30) * (DisplayLines - 30)];
+ int index = 0;
+ int brdCount = 0;
+ // skip top and bottom
+ for (int i = ScreenWidth * 30; i < smlBuff.Length - ScreenWidth * 30; i++)
+ {
+ if (brdCount < 30)
+ {
+ brdCount++;
+ continue;
+ }
+ if (brdCount > ScreenWidth - 30)
+ {
+ brdCount++;
+ continue;
+ }
+
+ smlBuff[index] = _frameBuffer[i];
+ index++;
+ brdCount++;
+ }
+
+ return smlBuff;
+
+ case ZXSpectrum.BorderType.Medium:
+ break;
+ }
+ */
+ return _frameBuffer;
+
}
#endregion
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.cs
index a700bf98ac..8de871a5e1 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.cs
@@ -11,12 +11,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
///
public abstract partial class SpectrumBase
{
-
+ // 128 and up only
protected int ROMPaged = 0;
protected bool SHADOWPaged;
protected int RAMPaged;
protected bool PagingDisabled;
+ // +3/+2A only
+ protected bool SpecialPagingMode;
+ protected int PagingConfiguration;
+
///
/// The calling ZXSpectrum class (piped in via constructor)
///
@@ -238,6 +242,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
ser.Sync("RAM5", ref RAM5, false);
ser.Sync("RAM6", ref RAM6, false);
ser.Sync("RAM7", ref RAM7, false);
+ ser.Sync("ROMPaged", ref ROMPaged);
+ ser.Sync("SHADOWPaged", ref SHADOWPaged);
+ ser.Sync("RAMPaged", ref RAMPaged);
+ ser.Sync("PagingDisabled", ref PagingDisabled);
+ ser.Sync("SpecialPagingMode", ref SpecialPagingMode);
+ ser.Sync("PagingConfiguration", ref PagingConfiguration);
RomData.SyncState(ser);
KeyboardDevice.SyncState(ser);
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Memory.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Memory.cs
index 27d74882fb..fca4961bd9 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Memory.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Memory.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -8,35 +9,50 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
public partial class ZX128Plus3 : 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.
+ /* http://www.worldofspectrum.org/faq/reference/128kreference.htm
+ *
+ * Port 0x7ffd behaves in the almost exactly the same way as on the 128K/+2, with two exceptions:
- * 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 +--------+--------+
+ Bit 4 is now the low bit of the ROM selection.
+ The partial decoding used is now slightly different: the hardware will respond only to those port addresses with bit 1 reset, bit 14 set and bit 15 reset (as opposed to just bits 1 and 15 reset on the 128K/+2).
+ The extra paging features of the +2A/+3 are controlled by port 0x1ffd (again, partial decoding applies here: the hardware will respond to all port addresses with bit 1 reset, bit 12 set and bits 13, 14 and 15 reset). This port is also write-only, and its last value should be saved at 0x5b67 (23399).
+
+ Port 0x1ffd responds as follows:
+
+ Bit 0: Paging mode. 0=normal, 1=special
+ Bit 1: In normal mode, ignored.
+ Bit 2: In normal mode, high bit of ROM selection. The four ROMs are:
+ ROM 0: 128k editor, menu system and self-test program
+ ROM 1: 128k syntax checker
+ ROM 2: +3DOS
+ ROM 3: 48 BASIC
+ Bit 3: Disk motor; 1=on, 0=off
+ Bit 4: Printer port strobe.
+ When special mode is selected, the memory map changes to one of four configurations specified in bits 1 and 2 of port 0x1ffd:
+ Bit 2 =0 Bit 2 =0 Bit 2 =1 Bit 2 =1
+ Bit 1 =0 Bit 1 =1 Bit 1 =0 Bit 1 =1
+ 0xffff +--------+ +--------+ +--------+ +--------+
+ | Bank 3 | | Bank 7 | | Bank 3 | | Bank 3 |
+ | | | | | | | |
+ | | | | | | | |
+ | | | screen | | | | |
+ 0xc000 +--------+ +--------+ +--------+ +--------+
+ | Bank 2 | | Bank 6 | | Bank 6 | | Bank 6 |
+ | | | | | | | |
+ | | | | | | | |
+ | | | | | | | |
+ 0x8000 +--------+ +--------+ +--------+ +--------+
+ | Bank 1 | | Bank 5 | | Bank 5 | | Bank 7 |
+ | | | | | | | |
+ | | | | | | | |
+ | | | screen | | screen | | screen |
+ 0x4000 +--------+ +--------+ +--------+ +--------+
+ | Bank 0 | | Bank 4 | | Bank 4 | | Bank 4 |
+ | | | | | | | |
+ | | | | | | | |
+ | | | | | | | |
+ 0x0000 +--------+ +--------+ +--------+ +--------+
+ RAM banks 1,3,4 and 6 are used for the disc cache and RAMdisc, while Bank 7 contains editor scratchpads and +3DOS workspace.
*/
///
@@ -49,58 +65,120 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
int divisor = addr / 0x4000;
byte result = 0xff;
- switch (divisor)
+
+ // special paging
+ if (SpecialPagingMode)
{
- // ROM 0x000
- case 0:
- if (ROMPaged == 0)
- result = Memory[0][addr % 0x4000];
- else
- result = Memory[1][addr % 0x4000];
- break;
+ switch (divisor)
+ {
+ case 0:
+ switch (PagingConfiguration)
+ {
+ case 0:
+ result = Memory[4][addr % 0x4000];
+ break;
+ case 1:
+ case 2:
+ case 3:
+ result = Memory[8][addr % 0x4000];
+ break;
+ }
+ break;
+ case 1:
+ switch (PagingConfiguration)
+ {
+ case 0:
+ result = Memory[5][addr % 0x4000];
+ break;
+ case 1:
+ case 2:
+ result = Memory[9][addr % 0x4000];
+ break;
+ case 3:
+ result = Memory[11][addr % 0x4000];
+ break;
+ }
+ break;
+ case 2:
+ switch (PagingConfiguration)
+ {
+ case 0:
+ result = Memory[6][addr % 0x4000];
+ break;
+ case 1:
+ case 2:
+ case 3:
+ result = Memory[10][addr % 0x4000];
+ break;
+ }
+ break;
+ case 3:
+ switch (PagingConfiguration)
+ {
+ case 0:
+ case 2:
+ case 3:
+ result = Memory[7][addr % 0x4000];
+ break;
+ case 1:
+ result = Memory[11][addr % 0x4000];
+ break;
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch (divisor)
+ {
+ // ROM 0x000
+ case 0:
+ result = Memory[ROMPaged][addr % 0x4000];
+ break;
- // RAM 0x4000 (RAM5 - Bank5 or shadow bank RAM7)
- case 1:
- result = Memory[7][addr % 0x4000];
- break;
+ // RAM 0x4000 (RAM5 - Bank5 or shadow bank RAM7)
+ case 1:
+ result = Memory[9][addr % 0x4000];
+ break;
- // RAM 0x8000 (RAM2 - Bank2)
- case 2:
- result = Memory[4][addr % 0x4000];
- break;
+ // RAM 0x8000 (RAM2 - Bank2)
+ case 2:
+ result = Memory[6][addr % 0x4000];
+ break;
- // RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
- case 3:
- switch (RAMPaged)
- {
- case 0:
- result = Memory[2][addr % 0x4000];
- break;
- case 1:
- result = Memory[3][addr % 0x4000];
- break;
- case 2:
- result = Memory[4][addr % 0x4000];
- break;
- case 3:
- result = Memory[5][addr % 0x4000];
- break;
- case 4:
- result = Memory[6][addr % 0x4000];
- break;
- case 5:
- result = Memory[7][addr % 0x4000];
- break;
- case 6:
- result = Memory[8][addr % 0x4000];
- break;
- case 7:
- result = Memory[9][addr % 0x4000];
- break;
- }
- break;
- default:
- break;
+ // RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
+ case 3:
+ switch (RAMPaged)
+ {
+ case 0:
+ result = Memory[4][addr % 0x4000];
+ break;
+ case 1:
+ result = Memory[5][addr % 0x4000];
+ break;
+ case 2:
+ result = Memory[6][addr % 0x4000];
+ break;
+ case 3:
+ result = Memory[7][addr % 0x4000];
+ break;
+ case 4:
+ result = Memory[8][addr % 0x4000];
+ break;
+ case 5:
+ result = Memory[9][addr % 0x4000];
+ break;
+ case 6:
+ result = Memory[10][addr % 0x4000];
+ break;
+ case 7:
+ result = Memory[11][addr % 0x4000];
+ break;
+ }
+ break;
+ default:
+ break;
+ }
}
return result;
@@ -115,59 +193,121 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
public override void WriteBus(ushort addr, byte value)
{
int divisor = addr / 0x4000;
- switch (divisor)
+
+ // special paging
+ if (SpecialPagingMode)
{
- // ROM 0x000
- case 0:
- if (ROMPaged == 0)
- Memory[0][addr % 0x4000] = value;
- else
- Memory[1][addr % 0x4000] = value;
- break;
-
- // RAM 0x4000 (RAM5 - Bank5 or shadow bank RAM7)
- case 1:
- Memory[7][addr % 0x4000] = value;
- break;
-
- // RAM 0x8000 (RAM2 - Bank2)
- case 2:
- Memory[4][addr % 0x4000] = value;
- break;
-
- // RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
- case 3:
- switch (RAMPaged)
- {
- case 0:
- Memory[2][addr % 0x4000] = value;
- break;
- case 1:
- Memory[3][addr % 0x4000] = value;
- break;
- case 2:
- Memory[4][addr % 0x4000] = value;
- break;
- case 3:
- Memory[5][addr % 0x4000] = value;
- break;
- case 4:
- Memory[6][addr % 0x4000] = value;
- break;
- case 5:
- Memory[7][addr % 0x4000] = value;
- break;
- case 6:
- Memory[8][addr % 0x4000] = value;
- break;
- case 7:
- Memory[9][addr % 0x4000] = value;
- break;
- }
- break;
- default:
- break;
+ switch (divisor)
+ {
+ case 0:
+ switch (PagingConfiguration)
+ {
+ case 0:
+ Memory[4][addr % 0x4000] = value;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ Memory[8][addr % 0x4000] = value;
+ break;
+ }
+ break;
+ case 1:
+ switch (PagingConfiguration)
+ {
+ case 0:
+ Memory[5][addr % 0x4000] = value;
+ break;
+ case 1:
+ case 2:
+ Memory[9][addr % 0x4000] = value;
+ break;
+ case 3:
+ Memory[11][addr % 0x4000] = value;
+ break;
+ }
+ break;
+ case 2:
+ switch (PagingConfiguration)
+ {
+ case 0:
+ Memory[6][addr % 0x4000] = value;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ Memory[10][addr % 0x4000] = value;
+ break;
+ }
+ break;
+ case 3:
+ switch (PagingConfiguration)
+ {
+ case 0:
+ case 2:
+ case 3:
+ Memory[7][addr % 0x4000] = value;
+ break;
+ case 1:
+ Memory[11][addr % 0x4000] = value;
+ break;
+ }
+ break;
+ }
}
+ else
+ {
+ switch (divisor)
+ {
+ // ROM 0x000
+ case 0:
+ Memory[ROMPaged][addr % 0x4000] = value;
+ break;
+
+ // RAM 0x4000 (RAM5 - Bank5 or shadow bank RAM7)
+ case 1:
+ Memory[9][addr % 0x4000] = value;
+ break;
+
+ // RAM 0x8000 (RAM2 - Bank2)
+ case 2:
+ Memory[6][addr % 0x4000] = value;
+ break;
+
+ // RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
+ case 3:
+ switch (RAMPaged)
+ {
+ case 0:
+ Memory[4][addr % 0x4000] = value;
+ break;
+ case 1:
+ Memory[5][addr % 0x4000] = value;
+ break;
+ case 2:
+ Memory[6][addr % 0x4000] = value;
+ break;
+ case 3:
+ Memory[7][addr % 0x4000] = value;
+ break;
+ case 4:
+ Memory[8][addr % 0x4000] = value;
+ break;
+ case 5:
+ Memory[9][addr % 0x4000] = value;
+ break;
+ case 6:
+ Memory[10][addr % 0x4000] = value;
+ break;
+ case 7:
+ Memory[11][addr % 0x4000] = value;
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
}
///
@@ -224,44 +364,54 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
Memory.Add(1, ROM1);
if (Memory.ContainsKey(2))
- Memory[2] = RAM0;
+ Memory[2] = ROM2;
else
- Memory.Add(2, RAM0);
+ Memory.Add(2, ROM2);
if (Memory.ContainsKey(3))
- Memory[3] = RAM1;
+ Memory[3] = ROM3;
else
- Memory.Add(3, RAM1);
+ Memory.Add(3, ROM3);
if (Memory.ContainsKey(4))
- Memory[4] = RAM2;
+ Memory[4] = RAM0;
else
- Memory.Add(4, RAM2);
+ Memory.Add(4, RAM0);
if (Memory.ContainsKey(5))
- Memory[5] = RAM3;
+ Memory[5] = RAM1;
else
- Memory.Add(5, RAM3);
+ Memory.Add(5, RAM1);
if (Memory.ContainsKey(6))
- Memory[6] = RAM4;
+ Memory[6] = RAM2;
else
- Memory.Add(6, RAM4);
+ Memory.Add(6, RAM2);
if (Memory.ContainsKey(7))
- Memory[7] = RAM5;
+ Memory[7] = RAM3;
else
- Memory.Add(7, RAM5);
+ Memory.Add(7, RAM3);
if (Memory.ContainsKey(8))
- Memory[8] = RAM6;
+ Memory[8] = RAM4;
else
- Memory.Add(8, RAM6);
+ Memory.Add(8, RAM4);
if (Memory.ContainsKey(9))
- Memory[9] = RAM7;
+ Memory[9] = RAM5;
else
- Memory.Add(9, RAM7);
+ Memory.Add(9, RAM5);
+
+ if (Memory.ContainsKey(10))
+ Memory[10] = RAM6;
+ else
+ Memory.Add(10, RAM6);
+
+ if (Memory.ContainsKey(11))
+ Memory[11] = RAM7;
+ else
+ Memory.Add(11, RAM7);
}
///
@@ -272,13 +422,18 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
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];
- ROM1[i] = RomData.RomBytes[i + 0x4000];
- }
+ // +3 uses ROM0, ROM1, ROM2 & ROM3
+ /* ROM 0: 128k editor, menu system and self-test program
+ ROM 1: 128k syntax checker
+ ROM 2: +3DOS
+ ROM 3: 48 BASIC
+ */
+ Stream stream = new MemoryStream(RomData.RomBytes);
+ stream.Read(ROM0, 0, 16384);
+ stream.Read(ROM1, 0, 16384);
+ stream.Read(ROM2, 0, 16384);
+ stream.Read(ROM3, 0, 16384);
+ stream.Dispose();
}
}
}
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs
index 9b6b458e4b..e7f2071fca 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Port.cs
@@ -79,30 +79,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
result |= (TAPE_BIT); // set is EAR Off
}
}
+ else if ((LastULAOutByte & 0x10) == 0)
+ {
+ result &= ~(0x40);
+ }
else
{
- if (KeyboardDevice.IsIssue2Keyboard)
- {
- if ((LastULAOutByte & (EAR_BIT + MIC_BIT)) == 0)
- {
- result &= ~(TAPE_BIT);
- }
- else
- {
- result |= TAPE_BIT;
- }
- }
- else
- {
- if ((LastULAOutByte & EAR_BIT) == 0)
- {
- result &= ~(TAPE_BIT);
- }
- else
- {
- result |= TAPE_BIT;
- }
- }
+ result |= 0x40;
}
}
@@ -111,9 +94,35 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
// devices other than the ULA will respond here
// (e.g. the AY sound chip in a 128k spectrum
- // AY register activate
- // Kemptson Mouse
+ // AY register activate - on +3/2a both FFFD and BFFD active AY
+ if ((port & 0xc002) == 0xc000)
+ {
+ result = (int)AYDevice.PortRead();
+ }
+ else if ((port & 0xc002) == 0x8000)
+ {
+ result = (int)AYDevice.PortRead();
+ }
+ // Kempston Mouse
+
+
+ else if ((port & 0xF002) == 0x2000) //Is bit 12 set and bits 13,14,15 and 1 reset?
+ {
+ //result = udpDrive.DiskStatusRead();
+ }
+ else if ((port & 0xF002) == 0x3000)
+ {
+ //result = udpDrive.DiskReadByte();
+ }
+
+ else if ((port & 0xF002) == 0x0)
+ {
+ if (PagingDisabled)
+ result = 0x1;
+ else
+ result = 0xff;
+ }
// if unused port the floating memory bus should be returned (still todo)
}
@@ -128,33 +137,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
///
public override void WritePort(ushort port, byte value)
{
- // paging
- if (port == 0x7ffd)
- {
- // Bits 0, 1, 2 select the RAM page
- var rp = value & 0x07;
- if (rp < 8)
- RAMPaged = rp;
-
- // ROM page
- if ((value & 0x10) != 0)
- {
- // 48k ROM
- ROMPaged = 1;
- }
- else
- {
- ROMPaged = 0;
- }
-
- // Bit 5 signifies that paging is disabled until next reboot
- if ((value & 0x20) != 0)
- PagingDisabled = true;
-
-
- return;
- }
-
// Check whether the low bit is reset
// Technically the ULA should respond to every even I/O address
bool lowBitReset = (port & 0x01) == 0;
@@ -183,6 +165,131 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
// Tape
TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
}
+
+ else
+ {
+ // AY Register activation
+ if ((port & 0xc002) == 0xc000)
+ {
+ var reg = value & 0x0f;
+ AYDevice.SelectedRegister = reg;
+ CPU.TotalExecutedCycles += 3;
+ }
+ else
+ {
+ if ((port & 0xC002) == 0x8000)
+ {
+ AYDevice.PortWrite(value);
+ CPU.TotalExecutedCycles += 3;
+ }
+ else
+ {
+ if ((port & 0xC002) == 0x4000) //Are bits 1 and 15 reset and bit 14 set?
+ {
+ // memory paging activate
+ if (PagingDisabled)
+ return;
+
+ // bit 5 handles paging disable (48k mode, persistent until next reboot)
+ if ((value & 0x20) != 0)
+ {
+ PagingDisabled = true;
+ }
+
+ // shadow screen
+ if ((value & 0x08) != 0)
+ {
+ SHADOWPaged = true;
+ }
+ else
+ {
+ SHADOWPaged = false;
+ }
+ }
+ else
+ {
+ //Extra Memory Paging feature activate
+ if ((port & 0xF002) == 0x1000) //Is bit 12 set and bits 13,14,15 and 1 reset?
+ {
+ if (PagingDisabled)
+ return;
+
+ // set disk motor state
+ //todo
+
+ if ((value & 0x08) != 0)
+ {
+ //diskDriveState |= (1 << 4);
+ }
+ else
+ {
+ //diskDriveState &= ~(1 << 4);
+ }
+
+ if ((value & 0x1) != 0)
+ {
+ // activate special paging mode
+ SpecialPagingMode = true;
+ PagingConfiguration = (value & 0x6 >> 1);
+ }
+ else
+ {
+ // normal paging mode
+ SpecialPagingMode = false;
+ }
+ }
+ else
+ {
+ // disk write port
+ if ((port & 0xF002) == 0x3000) //Is bit 12 set and bits 13,14,15 and 1 reset?
+ {
+ //udpDrive.DiskWriteByte((byte)(val & 0xff));
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ // paging
+ if (port == 0x7ffd)
+ {
+ if (PagingDisabled)
+ return;
+
+ LastULAOutByte = value;
+
+
+
+
+
+
+ // Bits 0, 1, 2 select the RAM page
+ var rp = value & 0x07;
+ if (rp < 8)
+ RAMPaged = rp;
+
+ // ROM page
+ if ((value & 0x10) != 0)
+ {
+ // 48k ROM
+ ROMPaged = 1;
+ }
+ else
+ {
+ ROMPaged = 0;
+ }
+
+ // Bit 5 signifies that paging is disabled until next reboot
+ if ((value & 0x20) != 0)
+ PagingDisabled = true;
+
+
+ return;
+ }
+
+
}
}
}
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.cs
index 199beb7d8d..cd5e8f81b2 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.cs
@@ -29,8 +29,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
// init addressable memory from ROM and RAM banks
ReInitMemory();
- //RAM = new byte[0x4000 + 0xC000];
-
//DisplayLineTime = 132;
VsyncNumerator = 3546900;
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.ISoundProvider.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.ISoundProvider.cs
index 02f144350c..402b7f292d 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.ISoundProvider.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.ISoundProvider.cs
@@ -9,8 +9,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
public partial class ZXSpectrum
{
- private FakeSyncSound _fakeSyncSound;
- private IAsyncSoundProvider ActiveSoundProvider;
private SoundProviderMixer SoundMixer;
}
}
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.IVideoProvider.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.IVideoProvider.cs
new file mode 100644
index 0000000000..073236a69d
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.IVideoProvider.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
+{
+ ///
+ /// Main IVideoProvider implementation is inside the machine classes
+ /// This is just some helper functions
+ ///
+ public partial class ZXSpectrum
+ {
+
+ }
+}
diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs
index 81d2a965fb..ac08f1bd3a 100644
--- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs
+++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs
@@ -48,6 +48,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
ControllerDefinition = ZXSpectrumControllerDefinition;
Init(MachineType.ZXSpectrum128Plus2, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
break;
+ case MachineType.ZXSpectrum128Plus3:
+ ControllerDefinition = ZXSpectrumControllerDefinition;
+ Init(MachineType.ZXSpectrum128Plus3, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
+ break;
default:
throw new InvalidOperationException("Machine not yet emulated");
}
@@ -146,6 +150,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
var romDataP2 = RomData.InitROM(machineType, _systemRomP2);
_machine.InitROM(romDataP2);
break;
+ case MachineType.ZXSpectrum128Plus3:
+ _machine = new ZX128Plus3(this, _cpu, file);
+ var _systemRomP3 = GetFirmware(0x10000, "PLUS3ROM");
+ var romDataP3 = RomData.InitROM(machineType, _systemRomP3);
+ _machine.InitROM(romDataP3);
+ break;
}
}