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]{};