CPCHawk: Start of the gate array implementation
This commit is contained in:
parent
aec496b561
commit
6863368dd3
|
@ -149,6 +149,7 @@
|
||||||
<Compile Include="Computers\AmstradCPC\Hardware\Disk\NECUPD765.IPortIODevice.cs" />
|
<Compile Include="Computers\AmstradCPC\Hardware\Disk\NECUPD765.IPortIODevice.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Hardware\Disk\NECUPD765.Timing.cs" />
|
<Compile Include="Computers\AmstradCPC\Hardware\Disk\NECUPD765.Timing.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Hardware\Disk\NECUPS765.Static.cs" />
|
<Compile Include="Computers\AmstradCPC\Hardware\Disk\NECUPS765.Static.cs" />
|
||||||
|
<Compile Include="Computers\AmstradCPC\Hardware\GateArray\AmstradGateArray.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Hardware\Input\StandardKeyboard.cs" />
|
<Compile Include="Computers\AmstradCPC\Hardware\Input\StandardKeyboard.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Hardware\SoundOutput\AY38912.cs" />
|
<Compile Include="Computers\AmstradCPC\Hardware\SoundOutput\AY38912.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Hardware\SoundOutput\Beeper.cs" />
|
<Compile Include="Computers\AmstradCPC\Hardware\SoundOutput\Beeper.cs" />
|
||||||
|
@ -164,7 +165,7 @@
|
||||||
<Compile Include="Computers\AmstradCPC\Machine\CPCBase.Port.cs" />
|
<Compile Include="Computers\AmstradCPC\Machine\CPCBase.Port.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Machine\GateArrayBase.cs" />
|
<Compile Include="Computers\AmstradCPC\Machine\GateArrayBase.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Machine\MachineType.cs" />
|
<Compile Include="Computers\AmstradCPC\Machine\MachineType.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Machine\PPIBase.cs" />
|
<Compile Include="Computers\AmstradCPC\Hardware\PPI\PPI_8255.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Media\Disk\CPCExtendedFloppyDisk.cs" />
|
<Compile Include="Computers\AmstradCPC\Media\Disk\CPCExtendedFloppyDisk.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Media\Disk\CPCFloppyDisk.cs" />
|
<Compile Include="Computers\AmstradCPC\Media\Disk\CPCFloppyDisk.cs" />
|
||||||
<Compile Include="Computers\AmstradCPC\Media\Disk\DiskType.cs" />
|
<Compile Include="Computers\AmstradCPC\Media\Disk\DiskType.cs" />
|
||||||
|
|
|
@ -24,6 +24,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
{
|
{
|
||||||
_machine = machine;
|
_machine = machine;
|
||||||
ChipType = chipType;
|
ChipType = chipType;
|
||||||
|
|
||||||
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -52,6 +54,114 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public short MA;
|
public short MA;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Lookups
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are not accessible on real hardware
|
||||||
|
* It just makes screen generation easier to have these accessbile from the gate array
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total frame width (in characters)
|
||||||
|
/// </summary>
|
||||||
|
public int FrameWidth
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (int)Regs[HOR_TOTAL] + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total frame height (in scanlines)
|
||||||
|
/// </summary>
|
||||||
|
public int FrameHeight
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ((int)Regs[VER_TOTAL] + 1) * ((int)Regs[MAX_RASTER_ADDR] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The width of the display area (in characters)
|
||||||
|
/// </summary>
|
||||||
|
public int DisplayWidth
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (int)Regs[HOR_DISPLAYED];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The width of the display area (in scanlines)
|
||||||
|
/// </summary>
|
||||||
|
public int DisplayHeight
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (int)Regs[VER_DISPLAYED] * ((int)Regs[MAX_RASTER_ADDR] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The character at which to start HSYNC
|
||||||
|
/// </summary>
|
||||||
|
public int HorizontalSyncPos
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (int)Regs[HOR_SYNC_POS];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Width (in characters) of the HSYNC
|
||||||
|
/// </summary>
|
||||||
|
public int HorizontalSyncWidth
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return HSYNCWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The vertical scanline at which to start VSYNC
|
||||||
|
/// </summary>
|
||||||
|
public int VerticalSyncPos
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (int)Regs[VER_SYNC_POS] * ((int)Regs[MAX_RASTER_ADDR] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Height (in scanlines) of the VSYNC
|
||||||
|
/// </summary>
|
||||||
|
public int VerticalSyncHeight
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return VSYNCWidth * ((int)Regs[MAX_RASTER_ADDR] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of scanlines in one character
|
||||||
|
/// </summary>
|
||||||
|
public int ScanlinesPerCharacter
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (int)Regs[MAX_RASTER_ADDR] + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Internal Registers and State
|
#region Internal Registers and State
|
||||||
|
@ -277,7 +387,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
// HSYNC in progress
|
// HSYNC in progress
|
||||||
HSYNCCounter++;
|
HSYNCCounter++;
|
||||||
|
|
||||||
if (HSYNCCounter == HSYNCWidth)
|
if (HSYNCCounter >= HSYNCWidth)
|
||||||
{
|
{
|
||||||
// end of HSYNC
|
// end of HSYNC
|
||||||
HSYNCCounter = 0;
|
HSYNCCounter = 0;
|
||||||
|
@ -304,6 +414,14 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
// end of the current scanline
|
// end of the current scanline
|
||||||
HCC = 0;
|
HCC = 0;
|
||||||
|
|
||||||
|
if (ChipType == CRCTType.UMC_UM6845R && VLC <= Regs[MAX_RASTER_ADDR])
|
||||||
|
{
|
||||||
|
// https://web.archive.org/web/20170501112330/http://www.grimware.org/doku.php/documentations/devices/crtc
|
||||||
|
// The MA is reloaded with the value from R12 and R13 when VCC=0 and VLC=0 (that's when a new CRTC screen begin).
|
||||||
|
// However, CRTC Type 1 keep updating the MA on every new scanline while VCC=0 (and VLC=<R9).
|
||||||
|
MA = (short)(((Regs[DISP_START_ADDR_H]) & 0xff) << 8 | (Regs[DISP_START_ADDR_L]) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
if (VSYNC)
|
if (VSYNC)
|
||||||
{
|
{
|
||||||
// VSYNC in progress
|
// VSYNC in progress
|
||||||
|
@ -335,6 +453,9 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
EndOfScreen = false;
|
EndOfScreen = false;
|
||||||
VLC = 0;
|
VLC = 0;
|
||||||
VCC = 0;
|
VCC = 0;
|
||||||
|
|
||||||
|
// populate MA address
|
||||||
|
MA = (short)(((Regs[DISP_START_ADDR_H]) & 0xff) << 8 | (Regs[DISP_START_ADDR_L]) & 0xff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -394,6 +515,9 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
|
|
||||||
// populate initial MA address
|
// populate initial MA address
|
||||||
MA = (short)(((Regs[DISP_START_ADDR_H]) & 0xff) << 8 | (Regs[DISP_START_ADDR_L]) & 0xff);
|
MA = (short)(((Regs[DISP_START_ADDR_H]) & 0xff) << 8 | (Regs[DISP_START_ADDR_L]) & 0xff);
|
||||||
|
|
||||||
|
// updates widths
|
||||||
|
UpdateWidths();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -454,38 +578,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
|
|
||||||
if (SelectedRegister == HOR_AND_VER_SYNC_WIDTHS)
|
if (SelectedRegister == HOR_AND_VER_SYNC_WIDTHS)
|
||||||
{
|
{
|
||||||
switch (ChipType)
|
UpdateWidths();
|
||||||
{
|
|
||||||
case CRCTType.Hitachi_HD6845S:
|
|
||||||
// Bits 7..4 define Vertical Sync Width. If 0 is programmed this gives 16 lines of VSYNC. Bits 3..0 define Horizontal Sync Width.
|
|
||||||
// If 0 is programmed no HSYNC is generated.
|
|
||||||
HSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 0) & 0x0F;
|
|
||||||
VSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 4) & 0x0F;
|
|
||||||
break;
|
|
||||||
case CRCTType.UMC_UM6845R:
|
|
||||||
// Bits 7..4 are ignored. Vertical Sync is fixed at 16 lines. Bits 3..0 define Horizontal Sync Width. If 0 is programmed no HSYNC is generated.
|
|
||||||
HSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 0) & 0x0F;
|
|
||||||
VSYNCWidth = 16;
|
|
||||||
break;
|
|
||||||
case CRCTType.Motorola_MC6845:
|
|
||||||
// Bits 7..4 are ignored. Vertical Sync is fixed at 16 lines. Bits 3..0 define Horizontal Sync Width. If 0 is programmed this gives a HSYNC width of 16.
|
|
||||||
HSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 0) & 0x0F;
|
|
||||||
if (HSYNCWidth == 0)
|
|
||||||
HSYNCWidth = 16;
|
|
||||||
VSYNCWidth = 16;
|
|
||||||
break;
|
|
||||||
case CRCTType.Amstrad_AMS40489:
|
|
||||||
case CRCTType.Amstrad_40226:
|
|
||||||
// Bits 7..4 define Vertical Sync Width. If 0 is programmed this gives 16 lines of VSYNC.Bits 3..0 define Horizontal Sync Width.
|
|
||||||
// If 0 is programmed this gives a HSYNC width of 16.
|
|
||||||
HSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 0) & 0x0F;
|
|
||||||
VSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 4) & 0x0F;
|
|
||||||
if (HSYNCWidth == 0)
|
|
||||||
HSYNCWidth = 16;
|
|
||||||
if (VSYNCWidth == 0)
|
|
||||||
VSYNCWidth = 16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,6 +686,45 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
return addressed;
|
return addressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the V and H SYNC widths
|
||||||
|
/// </summary>
|
||||||
|
private void UpdateWidths()
|
||||||
|
{
|
||||||
|
switch (ChipType)
|
||||||
|
{
|
||||||
|
case CRCTType.Hitachi_HD6845S:
|
||||||
|
// Bits 7..4 define Vertical Sync Width. If 0 is programmed this gives 16 lines of VSYNC. Bits 3..0 define Horizontal Sync Width.
|
||||||
|
// If 0 is programmed no HSYNC is generated.
|
||||||
|
HSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 0) & 0x0F;
|
||||||
|
VSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 4) & 0x0F;
|
||||||
|
break;
|
||||||
|
case CRCTType.UMC_UM6845R:
|
||||||
|
// Bits 7..4 are ignored. Vertical Sync is fixed at 16 lines. Bits 3..0 define Horizontal Sync Width. If 0 is programmed no HSYNC is generated.
|
||||||
|
HSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 0) & 0x0F;
|
||||||
|
VSYNCWidth = 16;
|
||||||
|
break;
|
||||||
|
case CRCTType.Motorola_MC6845:
|
||||||
|
// Bits 7..4 are ignored. Vertical Sync is fixed at 16 lines. Bits 3..0 define Horizontal Sync Width. If 0 is programmed this gives a HSYNC width of 16.
|
||||||
|
HSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 0) & 0x0F;
|
||||||
|
if (HSYNCWidth == 0)
|
||||||
|
HSYNCWidth = 16;
|
||||||
|
VSYNCWidth = 16;
|
||||||
|
break;
|
||||||
|
case CRCTType.Amstrad_AMS40489:
|
||||||
|
case CRCTType.Amstrad_40226:
|
||||||
|
// Bits 7..4 define Vertical Sync Width. If 0 is programmed this gives 16 lines of VSYNC.Bits 3..0 define Horizontal Sync Width.
|
||||||
|
// If 0 is programmed this gives a HSYNC width of 16.
|
||||||
|
HSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 0) & 0x0F;
|
||||||
|
VSYNCWidth = (Regs[HOR_AND_VER_SYNC_WIDTHS] >> 4) & 0x0F;
|
||||||
|
if (HSYNCWidth == 0)
|
||||||
|
HSYNCWidth = 16;
|
||||||
|
if (VSYNCWidth == 0)
|
||||||
|
VSYNCWidth = 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region PortIODevice
|
#region PortIODevice
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,13 +10,13 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
/// http://www.cpcwiki.eu/imgs/d/df/PPI_M5L8255AP-5.pdf
|
/// http://www.cpcwiki.eu/imgs/d/df/PPI_M5L8255AP-5.pdf
|
||||||
/// http://www.cpcwiki.eu/index.php/8255
|
/// http://www.cpcwiki.eu/index.php/8255
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PPIBase : IPortIODevice
|
public class PPI_8255 : IPortIODevice
|
||||||
{
|
{
|
||||||
#region Devices
|
#region Devices
|
||||||
|
|
||||||
private CPCBase _machine;
|
private CPCBase _machine;
|
||||||
private CRCT_6845 CRTC => _machine.CRCT;
|
private CRCT_6845 CRTC => _machine.CRCT;
|
||||||
private GateArrayBase GateArray => _machine.GateArray;
|
private AmstradGateArray GateArray => _machine.GateArray;
|
||||||
private IPSG PSG => _machine.AYDevice;
|
private IPSG PSG => _machine.AYDevice;
|
||||||
private DatacorderDevice Tape => _machine.TapeDevice;
|
private DatacorderDevice Tape => _machine.TapeDevice;
|
||||||
private IKeyboard Keyboard => _machine.KeyboardDevice;
|
private IKeyboard Keyboard => _machine.KeyboardDevice;
|
||||||
|
@ -63,7 +63,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
|
|
||||||
#region Construction
|
#region Construction
|
||||||
|
|
||||||
public PPIBase(CPCBase machine)
|
public PPI_8255(CPCBase machine)
|
||||||
{
|
{
|
||||||
_machine = machine;
|
_machine = machine;
|
||||||
Reset();
|
Reset();
|
|
@ -130,6 +130,9 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
if (RomData.RomBytes.Length > 0x4000)
|
if (RomData.RomBytes.Length > 0x4000)
|
||||||
ROM1[i] = RomData.RomBytes[i + 0x4000];
|
ROM1[i] = RomData.RomBytes[i + 0x4000];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LowerROMPaged = true;
|
||||||
|
UpperROMPaged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
FrameLength = 79872;
|
FrameLength = 79872;
|
||||||
|
|
||||||
CRCT = new CRCT_6845(CRCT_6845.CRCTType.Motorola_MC6845, this);
|
CRCT = new CRCT_6845(CRCT_6845.CRCTType.Motorola_MC6845, this);
|
||||||
GateArray = new GateArray_CPC464(this);
|
GateArray = new AmstradGateArray(this, AmstradGateArray.GateArrayType.Amstrad40007);
|
||||||
PPI = new PPIBase(this);
|
PPI = new PPI_8255(this);
|
||||||
|
|
||||||
KeyboardDevice = new StandardKeyboard(this);
|
KeyboardDevice = new StandardKeyboard(this);
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,12 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Amstrad gate array
|
/// The Amstrad gate array
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GateArrayBase GateArray { get; set; }
|
public AmstradGateArray GateArray { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The PPI contoller chip
|
/// The PPI contoller chip
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PPIBase PPI { get; set; }
|
public PPI_8255 PPI { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The length of a standard frame in CPU cycles
|
/// The length of a standard frame in CPU cycles
|
||||||
|
@ -154,20 +154,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
|
||||||
|
|
||||||
PollInput();
|
PollInput();
|
||||||
|
|
||||||
for (;;)
|
GateArray.SetupVideo();
|
||||||
|
|
||||||
|
while (!GateArray.FrameEnd)
|
||||||
{
|
{
|
||||||
// run the CPU Monitor cycle
|
GateArray.DoCycles();
|
||||||
//CPUMon.ExecuteCycle();
|
|
||||||
|
|
||||||
GateArray.ClockCycle();
|
|
||||||
|
|
||||||
// cycle the tape device
|
|
||||||
if (UPDDiskDevice == null || !UPDDiskDevice.FDD_IsDiskLoaded)
|
|
||||||
TapeDevice.TapeCycle();
|
|
||||||
|
|
||||||
// has frame end been reached?
|
|
||||||
if (GateArray.FrameEnd)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OverFlow = (int)CurrentFrameCycle - GateArray.FrameLength;
|
OverFlow = (int)CurrentFrameCycle - GateArray.FrameLength;
|
||||||
|
|
Loading…
Reference in New Issue