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;