diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type0.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type0.cs
index a9fc46ab3f..98693e0d5a 100644
--- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type0.cs
+++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type0.cs
@@ -15,12 +15,13 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
///
public override int CrtcType => 0;
- ///
- /// CRTC is clocked at 1MHz (16 GA cycles)
- ///
+ public override void Clock() => throw new InvalidOperationException("CRTC Type 0 not implemented yet");
+
+
+ /*
public override void Clock()
{
- base.Clock();
+ CheckReset();
int maxScanLine;
@@ -130,7 +131,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
hhclock = true;
}
- /* Hor active video */
if (HCC == 0)
{
// active display
@@ -143,7 +143,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
latch_hdisp = false;
}
- /* Hor sync */
if (hssstart || // start of horizontal sync
HSYNC) // already in horizontal sync
{
@@ -163,7 +162,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
HSYNC = false;
}
- /* Ver active video */
if (VCC == 0)
{
// active display
@@ -203,7 +201,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
}
- /* Address Generation */
int line = VLC;
if (R8_Interlace == 3)
@@ -222,7 +219,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
_RA = VLC;
}
- _LA = _vma;
+ ma = _vma;
// DISPTMG Generation
if (!latch_hdisp || !latch_vdisp)
@@ -238,7 +235,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
DISPTMG = true;
}
}
-
+ */
///
/// R3l: CRTC-type horizontal sync width independent helper function
diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type1.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type1.cs
index 129bf4c5af..9f02e75b4b 100644
--- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type1.cs
+++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type1.cs
@@ -14,13 +14,277 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
///
public override int CrtcType => 1;
+ private int cnt;
+
///
/// CRTC is clocked at 1MHz (16 GA cycles)
///
public override void Clock()
+ {
+ CheckReset();
+ cnt++;
+
+ // linear address generator clocked
+ ma = (ma + 1) & 0x3FFF;
+
+ // horizontal character counter clocked
+ HCC++;
+
+ if (HCC == R0_HorizontalTotal + 1) // C0 == R0
+ {
+ // new scanline
+ // increment raster counter
+ VLC++;
+
+ if (VLC == R9_MaxScanline + 1) // C9 == R9
+ {
+ // new character row
+ // vertical character counter reset
+ VLC = 0;
+
+ // incremement vertical character counter
+ VCC++;
+
+ if (VCC == R6_VerticalDisplayed) // C4 == R6
+ {
+ // vertical display is disabled
+ latch_vdisp = false;
+ }
+
+ if (VCC == R4_VerticalTotal + 1) // C4 == R4
+ {
+ // new CRTC frame
+ // vertical character counter reset
+ VCC = 0;
+
+ // vertical display enabled
+ latch_vdisp = true;
+
+ // cached VMA loaded with register start address
+ ma_store = (Register[R12_START_ADDR_H] << 8) | Register[R13_START_ADDR_L];
+ }
+
+ if (VCC == R7_VerticalSyncPosition) // C4 == R7
+ {
+ // VSYNC enabled
+ VSYNC = true;
+
+ // reset vertical sync counter
+ VSC = 0;
+ }
+
+ ma_row_start = ma_store;
+ }
+
+ if (VSYNC)
+ {
+ // increment vertical sync counter
+ VSC++;
+
+ if (VSC == R3_VerticalSyncWidth // C3h == R3h
+ || VSC == 0) // VSC counter wrap-around
+ {
+ // VSYNC disabled
+ VSYNC = false;
+ cnt = 0;
+ }
+ }
+
+ // H display is enabled
+ latch_hdisp = true;
+
+ // horizontal character counter reset
+ HCC = 0;
+
+ // VMA updated with row start address
+ ma = ma_row_start;
+ }
+
+ if (HCC == R1_HorizontalDisplayed) // CO == R1
+ {
+ // H display is disabled
+ latch_hdisp = false;
+
+ // current VMA is copied into memory
+ ma_store = ma;
+ }
+
+ if (HCC == R2_HorizontalSyncPosition) // C0 == R2
+ {
+ // HSYNC is enabled
+ HSYNC = true;
+
+ // reset horizontal sync counter
+ HSC = 0;
+ }
+
+ if (HSYNC)
+ {
+ // HSYNC still enabled - increment counter
+ HSC++;
+
+ if (HSC == R3_HorizontalSyncWidth // C3l == R3l
+ || HSC == 0) // HSC counter wrap-around
+ {
+ // disable HSYNC
+ HSYNC = false;
+ }
+ }
+
+ // outputs
+ if (!latch_hdisp || !latch_vdisp)
+ {
+ // HSYNC output pin is fed through a NOR gate with either 2 or 3 inputs
+ // - H Display
+ // - V Display
+ DISPTMG = false;
+ }
+ else
+ {
+ DISPTMG = true;
+ }
+ }
+
+ public void Clock2()
{
base.Clock();
+ ma = (ma + 1) & 0x3FFF;
+ HCC++;
+
+ // C0 == R0
+ if (HCC == R0_HorizontalTotal + 1)
+ {
+ // new scanline
+ HCC = 0;
+
+ // C9 == R9
+ if (++VLC == R9_MaxScanline + 1 || latch_vadjust)
+ {
+ VLC = 0;
+
+ // C4 == R4
+ if (++VCC == R4_VerticalTotal + 1)
+ {
+ latch_vadjust = true;
+
+ _vmaRowStart = (Register[R12_START_ADDR_H] << 8) | Register[R13_START_ADDR_L];
+
+ // C5 == R5
+ if (VTAC == R5_VerticalTotalAdjust)
+ {
+ latch_vadjust = false;
+ VCC = 0;
+ VTAC = 0;
+ }
+ else
+ {
+ VTAC++;
+ }
+ }
+ else
+ {
+ // MA set to row start at the beginning of each line
+ _vmaRowStart += R1_HorizontalDisplayed;
+ }
+
+ // C4 == 0
+ if (VCC == 0)
+ {
+ latch_vdisp = true;
+ }
+
+ if (VCC == R6_VerticalDisplayed)
+ {
+ latch_vdisp = false;
+ }
+ }
+
+ if (!latch_vadjust)
+ {
+ // C4 == R7
+ if (VCC == R7_VerticalSyncPosition && VLC == 0)
+ {
+ VSYNC = true;
+ VSC = 0;
+ }
+
+ if (VSYNC)
+ {
+ VSC++;
+
+ // C3h == R3h
+ if (VSC == R3_VerticalSyncWidth || VSC == 0)
+ {
+ VSYNC = false;
+ }
+ }
+ }
+
+
+ }
+
+ if (HCC == 0)
+ {
+ ma = _vmaRowStart;
+ }
+
+ // C0 == R2
+ if (HCC == R2_HorizontalSyncPosition)
+ {
+ HSYNC = true;
+ HSC = 0;
+ }
+ if (HSYNC)
+ {
+ if (R3_HorizontalSyncWidth > 0)
+ {
+ HSC++;
+ }
+
+ // C3l == R3l
+ if (HSC == R3_HorizontalSyncWidth)
+ {
+ HSYNC = false;
+ }
+ }
+
+ int dSkew = R8_Skew_CUDISP > 2 ? -1 : R8_Skew_CUDISP;
+
+ // C0 == 0
+ if (dSkew >= 0 && HCC == dSkew)
+ {
+ latch_hdisp = true;
+ }
+
+ // C0 == R1
+ if (dSkew >= 0 && HCC == R1_HorizontalDisplayed + dSkew)
+ {
+ latch_hdisp = false;
+ }
+
+
+
+
+ // outputs
+ if (!latch_hdisp || !latch_vdisp)
+ {
+ // HSYNC output pin is fed through a NOR gate with either 2 or 3 inputs
+ // - H Display
+ // - V Display
+ DISPTMG = false;
+ }
+ else
+ {
+ DISPTMG = true;
+ }
+ }
+
+
+ public void Clocko()
+ {
+ CheckReset();
+
int maxScanLine;
if (HCC == R0_HorizontalTotal)
@@ -227,7 +491,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
_RA = VLC;
}
- _LA = _vma;
+ ma = _vma;
// DISPTMG Generation
if (!latch_hdisp || !latch_vdisp)
diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type2.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type2.cs
index 63d2886612..64191fe60d 100644
--- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type2.cs
+++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type2.cs
@@ -1,5 +1,4 @@
-using BizHawk.Common.NumberExtensions;
-
+
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
{
///
@@ -16,231 +15,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
///
public override int CrtcType => 2;
- ///
- /// CRTC is clocked at 1MHz (16 GA cycles)
- ///
- public override void Clock()
- {
- base.Clock();
-
- int maxScanLine;
-
- if (HCC == R0_HorizontalTotal)
- {
- // end of displayable area reached
- // set up for the next line
- HCC = 0;
-
- // TODO: handle interlace setup
- if (R8_Interlace == 3)
- {
- // in interlace sync and video mask off bit 0 of the max scanline address
- maxScanLine = R9_MaxScanline & 0b11110;
- }
- else
- {
- maxScanLine = R9_MaxScanline;
- }
-
- if (VLC == maxScanLine)
- {
- // we have reached the final scanline within this vertical character row
- // move to next character
- VLC = 0;
-
- // TODO: implement vertical adjust
-
-
- if (VCC == R4_VerticalTotal)
- {
- // check the interlace mode
- if (R8_Interlace.Bit(0))
- {
- // toggle the field
- _field = !_field;
- }
- else
- {
- // stay on the even field
- _field = false;
- }
-
- // we have reached the end of the vertical display area
- // address loaded from start address register at the top of each field
- _vmaRowStart = (Register[R12_START_ADDR_H] << 8) | Register[R13_START_ADDR_L];
-
- // reset the vertical character counter
- VCC = 0;
-
- // increment field counter
- CFC++;
- }
- else
- {
- // row start address is increased by Horiztonal Displayed
- _vmaRowStart += R1_HorizontalDisplayed;
-
- // increment vertical character counter
- VCC++;
- }
- }
- else
- {
- // next scanline
- if (R8_Interlace == 3)
- {
- // interlace sync+video mode
- // vertical line counter increments by 2
- VLC += 2;
-
- // ensure vertical line counter is an even value
- VLC &= ~1;
- }
- else
- {
- // non-interlace mode
- // increment vertical line counter
- VLC++;
- }
- }
-
- // MA set to row start at the beginning of each line
- _vma = _vmaRowStart;
- }
- else
- {
- // next horizontal character (1us)
- // increment horizontal character counter
- HCC++;
-
- // increment VMA
- _vma++;
- }
-
- hssstart = false;
- hhclock = false;
-
- if (HCC == R2_HorizontalSyncPosition)
- {
- // start of horizontal sync
- hssstart = true;
- }
-
- if (HCC == R2_HorizontalSyncPosition / 2)
- {
- // we are half way through the line
- hhclock = true;
- }
-
- /* Hor active video */
- if (HCC == 0)
- {
- // active display
- latch_hdisp = true;
- }
-
- if (HCC == R1_HorizontalDisplayed)
- {
- // inactive display
- latch_hdisp = false;
- }
-
- /* Hor sync */
- if (hssstart || // start of horizontal sync
- HSYNC) // already in horizontal sync
- {
- // start of horizontal sync
- HSYNC = true;
- HSC++;
- }
- else
- {
- // reset hsync counter
- HSC = 0;
- }
-
- if (HSC == R3_HorizontalSyncWidth)
- {
- // end of horizontal sync
- HSYNC = false;
- }
-
- /* Ver active video */
- if (VCC == 0)
- {
- // active display
- latch_vdisp = true;
- }
-
- if (VCC == R6_VerticalDisplayed)
- {
- // inactive display
- latch_vdisp = false;
- }
-
- // vertical sync occurs at different times depending on the interlace field
- // even field: the same time as HSYNC
- // odd field: half a line later than HSYNC
- if ((!_field && hssstart) || (_field && hhclock))
- {
- if ((VCC == R7_VerticalSyncPosition && VLC == 0) // vsync starts on the first line
- || VSYNC) // vsync is already in progress
- {
- // start of vertical sync
- VSYNC = true;
- // increment vertical sync counter
- VSC++;
- }
- else
- {
- // reset vsync counter
- VSC = 0;
- }
-
- if (VSYNC && VSC == R3_VerticalSyncWidth - 1)
- {
- // end of vertical sync
- VSYNC = false;
- }
- }
-
-
- /* Address Generation */
- int line = VLC;
-
- if (R8_Interlace == 3)
- {
- // interlace sync+video mode
- // the least significant bit is based on the current field number
- int fNum = _field ? 1 : 0;
- int lNum = VLC.Bit(0) ? 1 : 0;
- line &= ~1;
-
- _RA = line & (fNum | lNum);
- }
- else
- {
- // raster address is just the VLC
- _RA = VLC;
- }
-
- _LA = _vma;
-
- // DISPTMG Generation
- if (!latch_hdisp || !latch_vdisp)
- {
- // HSYNC output pin is fed through a NOR gate with either 2 or 3 inputs
- // - H Display
- // - V Display
- // - TODO: R8 DISPTMG Skew (only on certain CRTC types)
- DISPTMG = false;
- }
- else
- {
- DISPTMG = true;
- }
- }
-
+ public override void Clock() => throw new InvalidOperationException("CRTC Type 2 not implemented yet");
///
/// R3l: CRTC-type horizontal sync width independent helper function
diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type3.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type3.cs
index 8d5cab6dac..7696588ece 100644
--- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type3.cs
+++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type3.cs
@@ -1,5 +1,4 @@
-using BizHawk.Common.NumberExtensions;
-
+
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
{
///
@@ -14,231 +13,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
///
public override int CrtcType => 3;
- ///
- /// CRTC is clocked at 1MHz (16 GA cycles)
- ///
- public override void Clock()
- {
- base.Clock();
-
- int maxScanLine;
-
- if (HCC == R0_HorizontalTotal)
- {
- // end of displayable area reached
- // set up for the next line
- HCC = 0;
-
- // TODO: handle interlace setup
- if (R8_Interlace == 3)
- {
- // in interlace sync and video mask off bit 0 of the max scanline address
- maxScanLine = R9_MaxScanline & 0b11110;
- }
- else
- {
- maxScanLine = R9_MaxScanline;
- }
-
- if (VLC == maxScanLine)
- {
- // we have reached the final scanline within this vertical character row
- // move to next character
- VLC = 0;
-
- // TODO: implement vertical adjust
-
-
- if (VCC == R4_VerticalTotal)
- {
- // check the interlace mode
- if (R8_Interlace.Bit(0))
- {
- // toggle the field
- _field = !_field;
- }
- else
- {
- // stay on the even field
- _field = false;
- }
-
- // we have reached the end of the vertical display area
- // address loaded from start address register at the top of each field
- _vmaRowStart = (Register[R12_START_ADDR_H] << 8) | Register[R13_START_ADDR_L];
-
- // reset the vertical character counter
- VCC = 0;
-
- // increment field counter
- CFC++;
- }
- else
- {
- // row start address is increased by Horiztonal Displayed
- _vmaRowStart += R1_HorizontalDisplayed;
-
- // increment vertical character counter
- VCC++;
- }
- }
- else
- {
- // next scanline
- if (R8_Interlace == 3)
- {
- // interlace sync+video mode
- // vertical line counter increments by 2
- VLC += 2;
-
- // ensure vertical line counter is an even value
- VLC &= ~1;
- }
- else
- {
- // non-interlace mode
- // increment vertical line counter
- VLC++;
- }
- }
-
- // MA set to row start at the beginning of each line
- _vma = _vmaRowStart;
- }
- else
- {
- // next horizontal character (1us)
- // increment horizontal character counter
- HCC++;
-
- // increment VMA
- _vma++;
- }
-
- hssstart = false;
- hhclock = false;
-
- if (HCC == R2_HorizontalSyncPosition)
- {
- // start of horizontal sync
- hssstart = true;
- }
-
- if (HCC == R2_HorizontalSyncPosition / 2)
- {
- // we are half way through the line
- hhclock = true;
- }
-
- /* Hor active video */
- if (HCC == 0)
- {
- // active display
- latch_hdisp = true;
- }
-
- if (HCC == R1_HorizontalDisplayed)
- {
- // inactive display
- latch_hdisp = false;
- }
-
- /* Hor sync */
- if (hssstart || // start of horizontal sync
- HSYNC) // already in horizontal sync
- {
- // start of horizontal sync
- HSYNC = true;
- HSC++;
- }
- else
- {
- // reset hsync counter
- HSC = 0;
- }
-
- if (HSC == R3_HorizontalSyncWidth)
- {
- // end of horizontal sync
- HSYNC = false;
- }
-
- /* Ver active video */
- if (VCC == 0)
- {
- // active display
- latch_vdisp = true;
- }
-
- if (VCC == R6_VerticalDisplayed)
- {
- // inactive display
- latch_vdisp = false;
- }
-
- // vertical sync occurs at different times depending on the interlace field
- // even field: the same time as HSYNC
- // odd field: half a line later than HSYNC
- if ((!_field && hssstart) || (_field && hhclock))
- {
- if ((VCC == R7_VerticalSyncPosition && VLC == 0) // vsync starts on the first line
- || VSYNC) // vsync is already in progress
- {
- // start of vertical sync
- VSYNC = true;
- // increment vertical sync counter
- VSC++;
- }
- else
- {
- // reset vsync counter
- VSC = 0;
- }
-
- if (VSYNC && VSC == R3_VerticalSyncWidth - 1)
- {
- // end of vertical sync
- VSYNC = false;
- }
- }
-
-
- /* Address Generation */
- int line = VLC;
-
- if (R8_Interlace == 3)
- {
- // interlace sync+video mode
- // the least significant bit is based on the current field number
- int fNum = _field ? 1 : 0;
- int lNum = VLC.Bit(0) ? 1 : 0;
- line &= ~1;
-
- _RA = line & (fNum | lNum);
- }
- else
- {
- // raster address is just the VLC
- _RA = VLC;
- }
-
- _LA = _vma;
-
- // DISPTMG Generation
- if (!latch_hdisp || !latch_vdisp)
- {
- // HSYNC output pin is fed through a NOR gate with either 2 or 3 inputs
- // - H Display
- // - V Display
- // - TODO: R8 DISPTMG Skew (only on certain CRTC types)
- DISPTMG = false;
- }
- else
- {
- DISPTMG = true;
- }
- }
-
+ public override void Clock() => throw new InvalidOperationException("CRTC Type 3 not implemented yet");
///
/// R3l: CRTC-type horizontal sync width independent helper function
diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type4.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type4.cs
index 4d30634320..66bbfcd4f5 100644
--- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type4.cs
+++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.Type4.cs
@@ -1,5 +1,4 @@
-using BizHawk.Common.NumberExtensions;
-
+
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
{
///
@@ -15,231 +14,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
///
public override int CrtcType => 4;
- ///
- /// CRTC is clocked at 1MHz (16 GA cycles)
- ///
- public override void Clock()
- {
- base.Clock();
-
- int maxScanLine;
-
- if (HCC == R0_HorizontalTotal)
- {
- // end of displayable area reached
- // set up for the next line
- HCC = 0;
-
- // TODO: handle interlace setup
- if (R8_Interlace == 3)
- {
- // in interlace sync and video mask off bit 0 of the max scanline address
- maxScanLine = R9_MaxScanline & 0b11110;
- }
- else
- {
- maxScanLine = R9_MaxScanline;
- }
-
- if (VLC == maxScanLine)
- {
- // we have reached the final scanline within this vertical character row
- // move to next character
- VLC = 0;
-
- // TODO: implement vertical adjust
-
-
- if (VCC == R4_VerticalTotal)
- {
- // check the interlace mode
- if (R8_Interlace.Bit(0))
- {
- // toggle the field
- _field = !_field;
- }
- else
- {
- // stay on the even field
- _field = false;
- }
-
- // we have reached the end of the vertical display area
- // address loaded from start address register at the top of each field
- _vmaRowStart = (Register[R12_START_ADDR_H] << 8) | Register[R13_START_ADDR_L];
-
- // reset the vertical character counter
- VCC = 0;
-
- // increment field counter
- CFC++;
- }
- else
- {
- // row start address is increased by Horiztonal Displayed
- _vmaRowStart += R1_HorizontalDisplayed;
-
- // increment vertical character counter
- VCC++;
- }
- }
- else
- {
- // next scanline
- if (R8_Interlace == 3)
- {
- // interlace sync+video mode
- // vertical line counter increments by 2
- VLC += 2;
-
- // ensure vertical line counter is an even value
- VLC &= ~1;
- }
- else
- {
- // non-interlace mode
- // increment vertical line counter
- VLC++;
- }
- }
-
- // MA set to row start at the beginning of each line
- _vma = _vmaRowStart;
- }
- else
- {
- // next horizontal character (1us)
- // increment horizontal character counter
- HCC++;
-
- // increment VMA
- _vma++;
- }
-
- hssstart = false;
- hhclock = false;
-
- if (HCC == R2_HorizontalSyncPosition)
- {
- // start of horizontal sync
- hssstart = true;
- }
-
- if (HCC == R2_HorizontalSyncPosition / 2)
- {
- // we are half way through the line
- hhclock = true;
- }
-
- /* Hor active video */
- if (HCC == 0)
- {
- // active display
- latch_hdisp = true;
- }
-
- if (HCC == R1_HorizontalDisplayed)
- {
- // inactive display
- latch_hdisp = false;
- }
-
- /* Hor sync */
- if (hssstart || // start of horizontal sync
- HSYNC) // already in horizontal sync
- {
- // start of horizontal sync
- HSYNC = true;
- HSC++;
- }
- else
- {
- // reset hsync counter
- HSC = 0;
- }
-
- if (HSC == R3_HorizontalSyncWidth)
- {
- // end of horizontal sync
- HSYNC = false;
- }
-
- /* Ver active video */
- if (VCC == 0)
- {
- // active display
- latch_vdisp = true;
- }
-
- if (VCC == R6_VerticalDisplayed)
- {
- // inactive display
- latch_vdisp = false;
- }
-
- // vertical sync occurs at different times depending on the interlace field
- // even field: the same time as HSYNC
- // odd field: half a line later than HSYNC
- if ((!_field && hssstart) || (_field && hhclock))
- {
- if ((VCC == R7_VerticalSyncPosition && VLC == 0) // vsync starts on the first line
- || VSYNC) // vsync is already in progress
- {
- // start of vertical sync
- VSYNC = true;
- // increment vertical sync counter
- VSC++;
- }
- else
- {
- // reset vsync counter
- VSC = 0;
- }
-
- if (VSYNC && VSC == R3_VerticalSyncWidth - 1)
- {
- // end of vertical sync
- VSYNC = false;
- }
- }
-
-
- /* Address Generation */
- int line = VLC;
-
- if (R8_Interlace == 3)
- {
- // interlace sync+video mode
- // the least significant bit is based on the current field number
- int fNum = _field ? 1 : 0;
- int lNum = VLC.Bit(0) ? 1 : 0;
- line &= ~1;
-
- _RA = line & (fNum | lNum);
- }
- else
- {
- // raster address is just the VLC
- _RA = VLC;
- }
-
- _LA = _vma;
-
- // DISPTMG Generation
- if (!latch_hdisp || !latch_vdisp)
- {
- // HSYNC output pin is fed through a NOR gate with either 2 or 3 inputs
- // - H Display
- // - V Display
- // - TODO: R8 DISPTMG Skew (only on certain CRTC types)
- DISPTMG = false;
- }
- else
- {
- DISPTMG = true;
- }
- }
-
+ public override void Clock() => throw new InvalidOperationException("CRTC Type 4 not implemented yet");
///
/// R3l: CRTC-type horizontal sync width independent helper function
diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.cs
index 7ae24c4dcf..9a84b633bc 100644
--- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.cs
+++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/CRTC.cs
@@ -137,7 +137,17 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
/// Character pos address (0 index).
/// Feeds the MA lines
///
- protected int _LA;
+ protected int ma;
+
+ ///
+ /// Memory address reset latch
+ ///
+ protected int ma_row_start;
+
+ ///
+ /// Internal latch for storing intermediate MA values
+ ///
+ protected int ma_store;
///
/// Generated by the Vertical Control Raster Counter
@@ -173,21 +183,21 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
{
var MA = new BitArray(16);
MA[0] = CLK;
- MA[1] = _LA.Bit(0);
- MA[2] = _LA.Bit(1);
- MA[3] = _LA.Bit(2);
- MA[4] = _LA.Bit(3);
- MA[5] = _LA.Bit(4);
- MA[6] = _LA.Bit(5);
- MA[7] = _LA.Bit(6);
- MA[8] = _LA.Bit(7);
- MA[9] = _LA.Bit(8);
- MA[10] = _LA.Bit(9);
- MA[11] = _RA.Bit(0);
- MA[12] = _RA.Bit(1);
- MA[13] = _RA.Bit(2);
- MA[14] = _LA.Bit(12);
- MA[15] = _LA.Bit(13);
+ MA[1] = ma.Bit(0);
+ MA[2] = ma.Bit(1);
+ MA[3] = ma.Bit(2);
+ MA[4] = ma.Bit(3);
+ MA[5] = ma.Bit(4);
+ MA[6] = ma.Bit(5);
+ MA[7] = ma.Bit(6);
+ MA[8] = ma.Bit(7);
+ MA[9] = ma.Bit(8);
+ MA[10] = ma.Bit(9);
+ MA[11] = VLC.Bit(0);
+ MA[12] = VLC.Bit(1);
+ MA[13] = VLC.Bit(2);
+ MA[14] = ma.Bit(12);
+ MA[15] = ma.Bit(13);
int[] array = new int[1];
MA.CopyTo(array, 0);
return (ushort)array[0];
@@ -616,7 +626,10 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
///
/// CRTC is clocked at 1MHz (16 GA cycles)
///
- public virtual void Clock()
+ public virtual void Clock() { }
+
+
+ public virtual void CheckReset()
{
if (_inReset > 0)
{
@@ -633,7 +646,9 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
_field = false;
_vmaRowStart = 0;
_vma = 0;
- _LA = 0;
+ ma = 0;
+ ma_row_start = 0;
+ ma_store = 0;
_RA = 0;
latch_hdisp = false;
latch_vdisp = false;
@@ -755,7 +770,9 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
ser.Sync(nameof(_HSYNC), ref _HSYNC);
ser.Sync(nameof(_DISPTMG), ref _DISPTMG);
ser.Sync(nameof(_CUDISP), ref _CUDISP);
- ser.Sync(nameof(_LA), ref _LA);
+ ser.Sync(nameof(ma), ref ma);
+ ser.Sync(nameof(ma_row_start), ref ma_row_start);
+ ser.Sync(nameof(ma_store), ref ma_store);
ser.Sync(nameof(_RA), ref _RA);
ser.Sync(nameof(_addressRegister), ref _addressRegister);
ser.Sync(nameof(Register), ref Register, false);
diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/GateArray.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/GateArray.cs
index 1f3029e3c0..60956ba41b 100644
--- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/GateArray.cs
+++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/GateArray.cs
@@ -51,6 +51,9 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
}
private int _GAClockCounter;
+ public double CRTCClockCounter => (double)GAClockCounter / 16;
+ public double CPUClockClounter => (double)GAClockCounter / 4;
+
///
/// Previous frame clock count. Latched at the end of the frame (VSYNC off)
@@ -514,6 +517,9 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
}
}
+ private int GAClockCounterOriginVSYNC;
+ private double GACunlockCounterOriginVSYNCCRTC => (double)GAClockCounterOriginVSYNC / 16;
+
///
/// Fired when CRTC VSYNC active signal is detected
///
@@ -525,6 +531,10 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
GA_VSYNC = true;
// black colour enabled for vsync
C_VSYNC_Black = true;
+
+ // signal start of new frame
+ GAClockCounterOriginVSYNC = 0;
+ FrameEnd = true;
}
///
@@ -609,6 +619,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
// We will do this for now to get the accuracy right, but will probably need to optimise this down the line
//OutputPixel(0);
GAClockCounter++;
+ GAClockCounterOriginVSYNC++;
// Based on timing oscilloscope traces from
diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC6128/CPC6128.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC6128/CPC6128.cs
index 792404a219..0c1429e2fa 100644
--- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC6128/CPC6128.cs
+++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC6128/CPC6128.cs
@@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
CPC = cpc;
CPU = cpu;
- CRTC = CRTC.Create(0);
+ CRTC = CRTC.Create(1);
GateArray = new GateArray(this, GateArrayType.Amstrad40010);
CRTScreen = new CRTScreen(ScreenType.CTM064x, borderType);
diff --git a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs
index 5e5b7a04a9..25dd7d9b85 100644
--- a/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs
+++ b/src/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs
@@ -148,7 +148,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
GateArray.GAClockCounter = 0;
GateArray.FrameEnd = false;
- while (!CRTScreen.FrameEnd)
+ while (!GateArray.FrameEnd)
{
GateArray.Clock();
@@ -157,7 +157,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
TapeDevice.TapeCycle();
}
- CRTScreen.FrameEnd = false;
+ GateArray.FrameEnd = false;
var ipf = GateArray.interruptsPerFrame;
GateArray.interruptsPerFrame = 0;