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; } }