diff --git a/BreaksPPU/PPUPlayer/VideoProcessing.cs b/BreaksPPU/PPUPlayer/VideoProcessing.cs
index 95b17b67..2438cb0f 100644
--- a/BreaksPPU/PPUPlayer/VideoProcessing.cs
+++ b/BreaksPPU/PPUPlayer/VideoProcessing.cs
@@ -183,16 +183,23 @@ void ProcessScanRGB()
{
if (CurrentScan < 240)
{
- var sample = ScanBuffer[ReadPtr];
+ int red = 0, green = 0, blue = 0;
- byte r = sample.RED;
- byte g = sample.GREEN;
- byte b = sample.BLUE;
+ for (int n = 0; n < ppu_features.SamplesPerPCLK; n++)
+ {
+ var sample = ScanBuffer[ReadPtr];
+ red += sample.RED;
+ green += sample.GREEN;
+ blue += sample.BLUE;
+ ReadPtr++;
+ }
+
+ byte r = (byte)(red / ppu_features.SamplesPerPCLK);
+ byte g = (byte)(green / ppu_features.SamplesPerPCLK);
+ byte b = (byte)(blue / ppu_features.SamplesPerPCLK);
field[CurrentScan * 256 + i] = Color.FromArgb(r, g, b);
}
-
- ReadPtr += ppu_features.SamplesPerPCLK;
}
CurrentScan++;
diff --git a/BreaksPPU/PPUSim/cram.cpp b/BreaksPPU/PPUSim/cram.cpp
index 676baab1..7f2d0391 100644
--- a/BreaksPPU/PPUSim/cram.cpp
+++ b/BreaksPPU/PPUSim/cram.cpp
@@ -52,7 +52,18 @@ namespace PPUSim
for (size_t n = 0; n < 6; n++)
{
- cb[n] = new CBBit(ppu);
+ switch (ppu->rev)
+ {
+ // TBD: Check how things are in other RGB PPUs.
+
+ case Revision::RP2C04_0003:
+ cb[n] = new CBBit_RGB(ppu);
+ break;
+
+ default:
+ cb[n] = new CBBit(ppu);
+ break;
+ }
}
}
@@ -286,4 +297,33 @@ namespace PPUSim
cram[row * cram_lane_cols + col][n] = bit_val;
}
}
+
+ ///
+ /// The different version for RGB PPU (the one studied) is that CRAM is Write-Only.
+ ///
+ void CBBit_RGB::sim(size_t bit_num, BaseLogic::TriState* cell, BaseLogic::TriState n_OE)
+ {
+ TriState PCLK = ppu->wire.PCLK;
+ TriState n_PCLK = ppu->wire.n_PCLK;
+ TriState n_DB_CB = ppu->wire.n_DB_CB;
+
+ if (n_DB_CB == TriState::Zero)
+ {
+ TriState DBBit = ppu->GetDBBit(bit_num);
+
+ if (*cell != TriState::Z && DBBit != TriState::Z)
+ {
+ *cell = DBBit;
+ }
+ }
+
+ if (PCLK == TriState::One)
+ {
+ ff.set(TriState::Zero);
+ }
+ else
+ {
+ ff.set(*cell);
+ }
+ }
}
diff --git a/BreaksPPU/PPUSim/cram.h b/BreaksPPU/PPUSim/cram.h
index 7892c36a..0e440914 100644
--- a/BreaksPPU/PPUSim/cram.h
+++ b/BreaksPPU/PPUSim/cram.h
@@ -6,6 +6,7 @@ namespace PPUSim
{
class CBBit
{
+ protected:
PPU* ppu = nullptr;
BaseLogic::FF ff;
@@ -16,11 +17,23 @@ namespace PPUSim
CBBit(PPU* parent) { ppu = parent; }
~CBBit() {}
- void sim(size_t bit_num, BaseLogic::TriState * cell, BaseLogic::TriState n_OE);
+ virtual void sim(size_t bit_num, BaseLogic::TriState * cell, BaseLogic::TriState n_OE);
BaseLogic::TriState get_CBOut(BaseLogic::TriState n_OE);
};
+ ///
+ /// Special version for RGB PPU.
+ ///
+ class CBBit_RGB : public CBBit
+ {
+ public:
+ CBBit_RGB(PPU* parent) : CBBit (parent) {}
+ ~CBBit_RGB() {}
+
+ virtual void sim(size_t bit_num, BaseLogic::TriState* cell, BaseLogic::TriState n_OE);
+ };
+
class CRAM
{
friend PPUSimUnitTest::UnitTest;
diff --git a/BreaksPPU/PPUSim/ppu.h b/BreaksPPU/PPUSim/ppu.h
index ba859112..befd5072 100644
--- a/BreaksPPU/PPUSim/ppu.h
+++ b/BreaksPPU/PPUSim/ppu.h
@@ -181,6 +181,7 @@ namespace PPUSim
friend HVDecoder;
friend FSM;
friend CBBit;
+ friend CBBit_RGB;
friend CRAM;
friend VideoOut;
friend Mux;
diff --git a/BreaksPPU/PPUSim/video_out.cpp b/BreaksPPU/PPUSim/video_out.cpp
index 8cd18d8f..356ae60f 100644
--- a/BreaksPPU/PPUSim/video_out.cpp
+++ b/BreaksPPU/PPUSim/video_out.cpp
@@ -91,28 +91,23 @@ namespace PPUSim
TriState n_PCLK = ppu->wire.n_PCLK;
TriState SYNC = ppu->fsm.SYNC;
+ for (size_t n = 0; n < 4; n++)
+ {
+ cc_latch1[n].set(ppu->wire.n_CC[n], PCLK);
+ cc_latch2[n].set(cc_latch1[n].nget(), n_PCLK);
+ }
+
if (composite)
{
TriState BURST = ppu->fsm.BURST;
cc_burst_latch.set(BURST, n_PCLK);
- for (size_t n = 0; n < 4; n++)
- {
- cc_latch1[n].set(ppu->wire.n_CC[n], PCLK);
- cc_latch2[n].set(cc_latch1[n].nget(), n_PCLK);
- }
-
sync_latch.set(NOT(SYNC), n_PCLK);
cb_latch.set(BURST, n_PCLK);
}
else
{
- for (size_t n = 0; n < 4; n++)
- {
- rgb_cc_latch[n].set(ppu->wire.n_CC[n], n_PCLK);
- }
-
rgb_sync_latch[0].set(SYNC, n_PCLK);
rgb_sync_latch[1].set(rgb_sync_latch[0].nget(), PCLK);
rgb_sync_latch[2].set(rgb_sync_latch[1].nget(), n_PCLK);
@@ -328,20 +323,10 @@ namespace PPUSim
{
if (VidOut_n_PICTURE == TriState::Zero)
{
- if (composite)
- {
- vout.RAW.CC0 = ToByte(cc_latch2[0].get());
- vout.RAW.CC1 = ToByte(cc_latch2[1].get());
- vout.RAW.CC2 = ToByte(cc_latch2[2].get());
- vout.RAW.CC3 = ToByte(cc_latch2[3].get());
- }
- else
- {
- vout.RAW.CC0 = ToByte(rgb_cc_latch[0].nget());
- vout.RAW.CC1 = ToByte(rgb_cc_latch[1].nget());
- vout.RAW.CC2 = ToByte(rgb_cc_latch[2].nget());
- vout.RAW.CC3 = ToByte(rgb_cc_latch[3].nget());
- }
+ vout.RAW.CC0 = ToByte(cc_latch2[0].get());
+ vout.RAW.CC1 = ToByte(cc_latch2[1].get());
+ vout.RAW.CC2 = ToByte(cc_latch2[2].get());
+ vout.RAW.CC3 = ToByte(cc_latch2[3].get());
vout.RAW.LL0 = ToByte(NOT(ppu->wire.n_LL[0]));
vout.RAW.LL1 = ToByte(NOT(ppu->wire.n_LL[1]));
vout.RAW.TR = ToByte(NOT(ppu->wire.n_TR));
@@ -662,8 +647,8 @@ namespace PPUSim
if (PCLK == TriState::One)
{
TriState unpacked[16]{};
- col[0] = rgb_cc_latch[2].nget();
- col[1] = rgb_cc_latch[3].nget();
+ col[0] = cc_latch2[2].nget();
+ col[1] = cc_latch2[3].nget();
col[2] = ppu->wire.n_LL[0];
col[3] = ppu->wire.n_LL[1];
@@ -683,8 +668,8 @@ namespace PPUSim
TriState n_TB = ppu->wire.n_TB;
TriState lum_in[2]{};
- lum_in[0] = NOR(n_PCLK, NOT(rgb_cc_latch[0].nget()));
- lum_in[1] = NOR(n_PCLK, NOT(rgb_cc_latch[1].nget()));
+ lum_in[0] = NOR(n_PCLK, NOT(cc_latch2[0].nget()));
+ lum_in[1] = NOR(n_PCLK, NOT(cc_latch2[1].nget()));
red_sel.sim(PCLK, n_TR, &rgb_output[12 * 0], lum_in);
green_sel.sim(PCLK, n_TG, &rgb_output[12 * 1], lum_in);
@@ -761,10 +746,10 @@ namespace PPUSim
// Latch all important signals
- vppu.wire.n_CC[0] = (FromByte(rawIn.RAW.CC0));
- vppu.wire.n_CC[1] = (FromByte(rawIn.RAW.CC1));
- vppu.wire.n_CC[2] = (FromByte(rawIn.RAW.CC2));
- vppu.wire.n_CC[3] = (FromByte(rawIn.RAW.CC3));
+ vppu.wire.n_CC[0] = NOT(FromByte(rawIn.RAW.CC0));
+ vppu.wire.n_CC[1] = NOT(FromByte(rawIn.RAW.CC1));
+ vppu.wire.n_CC[2] = NOT(FromByte(rawIn.RAW.CC2));
+ vppu.wire.n_CC[3] = NOT(FromByte(rawIn.RAW.CC3));
vppu.wire.n_LL[0] = NOT(FromByte(rawIn.RAW.LL0));
vppu.wire.n_LL[1] = NOT(FromByte(rawIn.RAW.LL1));
vppu.wire.n_TR = NOT(FromByte(rawIn.RAW.TR));
@@ -774,23 +759,17 @@ namespace PPUSim
vppu.fsm.SYNC = FromByte(rawIn.RAW.Sync);
vppu.fsm.n_PICTURE = TriState::Zero;
- // Save the values on the input latches
+ size_t numHalfs = 6;
vppu.wire.n_PCLK = TriState::One;
vppu.wire.PCLK = TriState::Zero;
- vppu.vid_out->sim(rgbOut);
- // Color Matrix Conversion
-
- vppu.wire.n_PCLK = TriState::Zero;
- vppu.wire.PCLK = TriState::One;
- vppu.vid_out->sim(rgbOut);
-
- // Output the value to the output latches
-
- vppu.wire.n_PCLK = TriState::One;
- vppu.wire.PCLK = TriState::Zero;
- vppu.vid_out->sim(rgbOut);
+ for (size_t n = 0; n < numHalfs; n++)
+ {
+ vppu.vid_out->sim(rgbOut);
+ vppu.wire.n_PCLK = NOT(vppu.wire.n_PCLK);
+ vppu.wire.PCLK = NOT(vppu.wire.PCLK);
+ }
}
#pragma endregion "RGB PPU Stuff"
diff --git a/BreaksPPU/PPUSim/video_out.h b/BreaksPPU/PPUSim/video_out.h
index a3a79025..783850f7 100644
--- a/BreaksPPU/PPUSim/video_out.h
+++ b/BreaksPPU/PPUSim/video_out.h
@@ -51,7 +51,6 @@ namespace PPUSim
BaseLogic::DLatch npicture_latch2;
// For RGB PPU
- BaseLogic::DLatch rgb_cc_latch[4]{};
BaseLogic::DLatch rgb_sync_latch[3]{};
BaseLogic::DLatch rgb_red_latch[8]{};
BaseLogic::DLatch rgb_green_latch[8]{};