More +3 stuff (still not working)
This commit is contained in:
parent
43ed79cd64
commit
eff8ce69b4
|
@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Common
|
||||||
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", 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
|
// 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
|
||||||
|
|
|
@ -1391,6 +1391,7 @@
|
||||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Keyboard.cs" />
|
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Keyboard.cs" />
|
||||||
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Port.cs" />
|
<Compile Include="Computers\SinclairSpectrum\Machine\ZXSpectrum48K\ZX48.Port.cs" />
|
||||||
<None Include="Computers\SinclairSpectrum\readme.md" />
|
<None Include="Computers\SinclairSpectrum\readme.md" />
|
||||||
|
<Compile Include="Computers\SinclairSpectrum\ZXSpectrum.IVideoProvider.cs" />
|
||||||
<None Include="Consoles\Atari\docs\stella.pdf" />
|
<None Include="Consoles\Atari\docs\stella.pdf" />
|
||||||
<None Include="Consoles\Coleco\docs\colecovision tech1.pdf" />
|
<None Include="Consoles\Coleco\docs\colecovision tech1.pdf" />
|
||||||
<None Include="Consoles\Coleco\docs\colecovision tech2.pdf" />
|
<None Include="Consoles\Coleco\docs\colecovision tech2.pdf" />
|
||||||
|
|
|
@ -19,8 +19,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
ZXSpectrum128,
|
ZXSpectrum128,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sinclair Spectrum 128 + 2 model
|
/// Sinclair Spectrum 128 +2 model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ZXSpectrum128Plus2
|
ZXSpectrum128Plus2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sinclair Spectrum 128 +3 model
|
||||||
|
/// </summary>
|
||||||
|
ZXSpectrum128Plus3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -913,13 +913,44 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
*/
|
*/
|
||||||
public int[] GetVideoBuffer()
|
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
|
case ZXSpectrum.BorderType.Small:
|
||||||
int[] trans = new int[_frameBuffer.Length];
|
// leave only 10 border units all around
|
||||||
for (int i = 0; i < _frameBuffer.Length; i++)
|
int[] smlBuff = new int[(ScreenWidth - 30) * (DisplayLines - 30)];
|
||||||
trans[i] = ULAPalette[_frameBuffer[i]];
|
int index = 0;
|
||||||
return trans; //_frameBuffer;
|
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
|
#endregion
|
||||||
|
|
|
@ -11,12 +11,16 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract partial class SpectrumBase
|
public abstract partial class SpectrumBase
|
||||||
{
|
{
|
||||||
|
// 128 and up only
|
||||||
protected int ROMPaged = 0;
|
protected int ROMPaged = 0;
|
||||||
protected bool SHADOWPaged;
|
protected bool SHADOWPaged;
|
||||||
protected int RAMPaged;
|
protected int RAMPaged;
|
||||||
protected bool PagingDisabled;
|
protected bool PagingDisabled;
|
||||||
|
|
||||||
|
// +3/+2A only
|
||||||
|
protected bool SpecialPagingMode;
|
||||||
|
protected int PagingConfiguration;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The calling ZXSpectrum class (piped in via constructor)
|
/// The calling ZXSpectrum class (piped in via constructor)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -238,6 +242,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
ser.Sync("RAM5", ref RAM5, false);
|
ser.Sync("RAM5", ref RAM5, false);
|
||||||
ser.Sync("RAM6", ref RAM6, false);
|
ser.Sync("RAM6", ref RAM6, false);
|
||||||
ser.Sync("RAM7", ref RAM7, 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);
|
RomData.SyncState(ser);
|
||||||
KeyboardDevice.SyncState(ser);
|
KeyboardDevice.SyncState(ser);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -8,35 +9,50 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
{
|
{
|
||||||
public partial class ZX128Plus3 : SpectrumBase
|
public partial class ZX128Plus3 : SpectrumBase
|
||||||
{
|
{
|
||||||
/* 128k paging controlled by writes to port 0x7ffd
|
/* 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:
|
||||||
|
|
||||||
#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 +--------+--------+--------+--------+--------+--------+--------+--------+
|
Bit 4 is now the low bit of the ROM selection.
|
||||||
| Bank 0 | Bank 1 | Bank 2 | Bank 3 | Bank 4 | Bank 5 | Bank 6 | Bank 7 |
|
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).
|
||||||
| | |(also at| | |(also at| | |
|
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).
|
||||||
| | | 0x8000)| | | 0x4000)| | |
|
|
||||||
| | | | | | screen | | screen |
|
Port 0x1ffd responds as follows:
|
||||||
0xc000 +--------+--------+--------+--------+--------+--------+--------+--------+
|
|
||||||
| Bank 2 | Any one of these pages may be switched in.
|
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
|
||||||
0x8000 +--------+
|
ROM 1: 128k syntax checker
|
||||||
| Bank 5 |
|
ROM 2: +3DOS
|
||||||
| |
|
ROM 3: 48 BASIC
|
||||||
| |
|
Bit 3: Disk motor; 1=on, 0=off
|
||||||
| screen |
|
Bit 4: Printer port strobe.
|
||||||
0x4000 +--------+--------+
|
When special mode is selected, the memory map changes to one of four configurations specified in bits 1 and 2 of port 0x1ffd:
|
||||||
| ROM 0 | ROM 1 | Either ROM may be switched in.
|
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 |
|
||||||
0x0000 +--------+--------+
|
| | | | | | | |
|
||||||
|
| | | | | | | |
|
||||||
|
| | | 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -49,58 +65,120 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
{
|
{
|
||||||
int divisor = addr / 0x4000;
|
int divisor = addr / 0x4000;
|
||||||
byte result = 0xff;
|
byte result = 0xff;
|
||||||
switch (divisor)
|
|
||||||
|
// special paging
|
||||||
|
if (SpecialPagingMode)
|
||||||
{
|
{
|
||||||
// ROM 0x000
|
switch (divisor)
|
||||||
case 0:
|
{
|
||||||
if (ROMPaged == 0)
|
case 0:
|
||||||
result = Memory[0][addr % 0x4000];
|
switch (PagingConfiguration)
|
||||||
else
|
{
|
||||||
result = Memory[1][addr % 0x4000];
|
case 0:
|
||||||
break;
|
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)
|
// RAM 0x4000 (RAM5 - Bank5 or shadow bank RAM7)
|
||||||
case 1:
|
case 1:
|
||||||
result = Memory[7][addr % 0x4000];
|
result = Memory[9][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// RAM 0x8000 (RAM2 - Bank2)
|
// RAM 0x8000 (RAM2 - Bank2)
|
||||||
case 2:
|
case 2:
|
||||||
result = Memory[4][addr % 0x4000];
|
result = Memory[6][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
|
// RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
|
||||||
case 3:
|
case 3:
|
||||||
switch (RAMPaged)
|
switch (RAMPaged)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
result = Memory[2][addr % 0x4000];
|
result = Memory[4][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
result = Memory[3][addr % 0x4000];
|
result = Memory[5][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
result = Memory[4][addr % 0x4000];
|
result = Memory[6][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
result = Memory[5][addr % 0x4000];
|
result = Memory[7][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
result = Memory[6][addr % 0x4000];
|
result = Memory[8][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
result = Memory[7][addr % 0x4000];
|
result = Memory[9][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
result = Memory[8][addr % 0x4000];
|
result = Memory[10][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
result = Memory[9][addr % 0x4000];
|
result = Memory[11][addr % 0x4000];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -115,59 +193,121 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
public override void WriteBus(ushort addr, byte value)
|
public override void WriteBus(ushort addr, byte value)
|
||||||
{
|
{
|
||||||
int divisor = addr / 0x4000;
|
int divisor = addr / 0x4000;
|
||||||
switch (divisor)
|
|
||||||
|
// special paging
|
||||||
|
if (SpecialPagingMode)
|
||||||
{
|
{
|
||||||
// ROM 0x000
|
switch (divisor)
|
||||||
case 0:
|
{
|
||||||
if (ROMPaged == 0)
|
case 0:
|
||||||
Memory[0][addr % 0x4000] = value;
|
switch (PagingConfiguration)
|
||||||
else
|
{
|
||||||
Memory[1][addr % 0x4000] = value;
|
case 0:
|
||||||
break;
|
Memory[4][addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
// RAM 0x4000 (RAM5 - Bank5 or shadow bank RAM7)
|
case 1:
|
||||||
case 1:
|
case 2:
|
||||||
Memory[7][addr % 0x4000] = value;
|
case 3:
|
||||||
break;
|
Memory[8][addr % 0x4000] = value;
|
||||||
|
break;
|
||||||
// RAM 0x8000 (RAM2 - Bank2)
|
}
|
||||||
case 2:
|
break;
|
||||||
Memory[4][addr % 0x4000] = value;
|
case 1:
|
||||||
break;
|
switch (PagingConfiguration)
|
||||||
|
{
|
||||||
// RAM 0xc000 (any ram bank 0 - 7 may be paged in - default bank0)
|
case 0:
|
||||||
case 3:
|
Memory[5][addr % 0x4000] = value;
|
||||||
switch (RAMPaged)
|
break;
|
||||||
{
|
case 1:
|
||||||
case 0:
|
case 2:
|
||||||
Memory[2][addr % 0x4000] = value;
|
Memory[9][addr % 0x4000] = value;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 3:
|
||||||
Memory[3][addr % 0x4000] = value;
|
Memory[11][addr % 0x4000] = value;
|
||||||
break;
|
break;
|
||||||
case 2:
|
}
|
||||||
Memory[4][addr % 0x4000] = value;
|
break;
|
||||||
break;
|
case 2:
|
||||||
case 3:
|
switch (PagingConfiguration)
|
||||||
Memory[5][addr % 0x4000] = value;
|
{
|
||||||
break;
|
case 0:
|
||||||
case 4:
|
Memory[6][addr % 0x4000] = value;
|
||||||
Memory[6][addr % 0x4000] = value;
|
break;
|
||||||
break;
|
case 1:
|
||||||
case 5:
|
case 2:
|
||||||
Memory[7][addr % 0x4000] = value;
|
case 3:
|
||||||
break;
|
Memory[10][addr % 0x4000] = value;
|
||||||
case 6:
|
break;
|
||||||
Memory[8][addr % 0x4000] = value;
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 3:
|
||||||
Memory[9][addr % 0x4000] = value;
|
switch (PagingConfiguration)
|
||||||
break;
|
{
|
||||||
}
|
case 0:
|
||||||
break;
|
case 2:
|
||||||
default:
|
case 3:
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -224,44 +364,54 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
Memory.Add(1, ROM1);
|
Memory.Add(1, ROM1);
|
||||||
|
|
||||||
if (Memory.ContainsKey(2))
|
if (Memory.ContainsKey(2))
|
||||||
Memory[2] = RAM0;
|
Memory[2] = ROM2;
|
||||||
else
|
else
|
||||||
Memory.Add(2, RAM0);
|
Memory.Add(2, ROM2);
|
||||||
|
|
||||||
if (Memory.ContainsKey(3))
|
if (Memory.ContainsKey(3))
|
||||||
Memory[3] = RAM1;
|
Memory[3] = ROM3;
|
||||||
else
|
else
|
||||||
Memory.Add(3, RAM1);
|
Memory.Add(3, ROM3);
|
||||||
|
|
||||||
if (Memory.ContainsKey(4))
|
if (Memory.ContainsKey(4))
|
||||||
Memory[4] = RAM2;
|
Memory[4] = RAM0;
|
||||||
else
|
else
|
||||||
Memory.Add(4, RAM2);
|
Memory.Add(4, RAM0);
|
||||||
|
|
||||||
if (Memory.ContainsKey(5))
|
if (Memory.ContainsKey(5))
|
||||||
Memory[5] = RAM3;
|
Memory[5] = RAM1;
|
||||||
else
|
else
|
||||||
Memory.Add(5, RAM3);
|
Memory.Add(5, RAM1);
|
||||||
|
|
||||||
if (Memory.ContainsKey(6))
|
if (Memory.ContainsKey(6))
|
||||||
Memory[6] = RAM4;
|
Memory[6] = RAM2;
|
||||||
else
|
else
|
||||||
Memory.Add(6, RAM4);
|
Memory.Add(6, RAM2);
|
||||||
|
|
||||||
if (Memory.ContainsKey(7))
|
if (Memory.ContainsKey(7))
|
||||||
Memory[7] = RAM5;
|
Memory[7] = RAM3;
|
||||||
else
|
else
|
||||||
Memory.Add(7, RAM5);
|
Memory.Add(7, RAM3);
|
||||||
|
|
||||||
if (Memory.ContainsKey(8))
|
if (Memory.ContainsKey(8))
|
||||||
Memory[8] = RAM6;
|
Memory[8] = RAM4;
|
||||||
else
|
else
|
||||||
Memory.Add(8, RAM6);
|
Memory.Add(8, RAM4);
|
||||||
|
|
||||||
if (Memory.ContainsKey(9))
|
if (Memory.ContainsKey(9))
|
||||||
Memory[9] = RAM7;
|
Memory[9] = RAM5;
|
||||||
else
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -272,13 +422,18 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
public override void InitROM(RomData romData)
|
public override void InitROM(RomData romData)
|
||||||
{
|
{
|
||||||
RomData = romData;
|
RomData = romData;
|
||||||
// 128k uses ROM0 and ROM1
|
// +3 uses ROM0, ROM1, ROM2 & ROM3
|
||||||
// 128k loader is in ROM0, and fallback 48k rom is in ROM1
|
/* ROM 0: 128k editor, menu system and self-test program
|
||||||
for (int i = 0; i < 0x4000; i++)
|
ROM 1: 128k syntax checker
|
||||||
{
|
ROM 2: +3DOS
|
||||||
ROM0[i] = RomData.RomBytes[i];
|
ROM 3: 48 BASIC
|
||||||
ROM1[i] = RomData.RomBytes[i + 0x4000];
|
*/
|
||||||
}
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,30 +79,13 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
result |= (TAPE_BIT); // set is EAR Off
|
result |= (TAPE_BIT); // set is EAR Off
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((LastULAOutByte & 0x10) == 0)
|
||||||
|
{
|
||||||
|
result &= ~(0x40);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (KeyboardDevice.IsIssue2Keyboard)
|
result |= 0x40;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -111,9 +94,35 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
// devices other than the ULA will respond here
|
// devices other than the ULA will respond here
|
||||||
// (e.g. the AY sound chip in a 128k spectrum
|
// (e.g. the AY sound chip in a 128k spectrum
|
||||||
|
|
||||||
// AY register activate
|
// AY register activate - on +3/2a both FFFD and BFFD active AY
|
||||||
// Kemptson Mouse
|
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)
|
// if unused port the floating memory bus should be returned (still todo)
|
||||||
}
|
}
|
||||||
|
@ -128,33 +137,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
/// <param name="value"></param>
|
/// <param name="value"></param>
|
||||||
public override void WritePort(ushort port, byte value)
|
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
|
// Check whether the low bit is reset
|
||||||
// Technically the ULA should respond to every even I/O address
|
// Technically the ULA should respond to every even I/O address
|
||||||
bool lowBitReset = (port & 0x01) == 0;
|
bool lowBitReset = (port & 0x01) == 0;
|
||||||
|
@ -183,6 +165,131 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
// Tape
|
// Tape
|
||||||
TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
// init addressable memory from ROM and RAM banks
|
// init addressable memory from ROM and RAM banks
|
||||||
ReInitMemory();
|
ReInitMemory();
|
||||||
|
|
||||||
//RAM = new byte[0x4000 + 0xC000];
|
|
||||||
|
|
||||||
//DisplayLineTime = 132;
|
//DisplayLineTime = 132;
|
||||||
VsyncNumerator = 3546900;
|
VsyncNumerator = 3546900;
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
{
|
{
|
||||||
public partial class ZXSpectrum
|
public partial class ZXSpectrum
|
||||||
{
|
{
|
||||||
private FakeSyncSound _fakeSyncSound;
|
|
||||||
private IAsyncSoundProvider ActiveSoundProvider;
|
|
||||||
private SoundProviderMixer SoundMixer;
|
private SoundProviderMixer SoundMixer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Main IVideoProvider implementation is inside the machine classes
|
||||||
|
/// This is just some helper functions
|
||||||
|
/// </summary>
|
||||||
|
public partial class ZXSpectrum
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,6 +48,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
ControllerDefinition = ZXSpectrumControllerDefinition;
|
ControllerDefinition = ZXSpectrumControllerDefinition;
|
||||||
Init(MachineType.ZXSpectrum128Plus2, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
|
Init(MachineType.ZXSpectrum128Plus2, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
|
||||||
break;
|
break;
|
||||||
|
case MachineType.ZXSpectrum128Plus3:
|
||||||
|
ControllerDefinition = ZXSpectrumControllerDefinition;
|
||||||
|
Init(MachineType.ZXSpectrum128Plus3, SyncSettings.BorderType, SyncSettings.TapeLoadSpeed, _file);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException("Machine not yet emulated");
|
throw new InvalidOperationException("Machine not yet emulated");
|
||||||
}
|
}
|
||||||
|
@ -146,6 +150,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
||||||
var romDataP2 = RomData.InitROM(machineType, _systemRomP2);
|
var romDataP2 = RomData.InitROM(machineType, _systemRomP2);
|
||||||
_machine.InitROM(romDataP2);
|
_machine.InitROM(romDataP2);
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue