diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper.cs index 75c6b55..9dfefae 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper.cs @@ -78,6 +78,7 @@ namespace VirtualNes.Core public static Mapper CreateMapper(NES parent, int no) { + //todo : 实现加载mapper switch (no) { default: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs index 118698e..997017e 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs @@ -8,6 +8,8 @@ namespace VirtualNes.Core { public class NES { + public const int FETCH_CYCLES = 8; + public CPU cpu; public PPU ppu; public APU apu; @@ -181,7 +183,25 @@ namespace VirtualNes.Core if (RenderMethod < EnumRenderMethod.POST_RENDER) { EmulationCPU(nescfg.ScanlineCycles); + ppu.FrameStart(); + ppu.ScanlineNext(); + mapper.HSync(scanline); + ppu.ScanlineStart(); } + else + { + EmulationCPU(nescfg.HDrawCycles); + ppu.FrameStart(); + ppu.ScanlineNext(); + mapper.HSync(scanline); + EmulationCPU(FETCH_CYCLES * 32); + ppu.ScanlineStart(); + EmulationCPU(FETCH_CYCLES * 10 + nescfg.ScanlineEndCycles); + } + } + else if (scanline < 240) + { + } } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs index f5b64b3..ef7e7fa 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs @@ -363,6 +363,68 @@ namespace VirtualNes.Core MemoryUtility.memset(lpColormode, 0, (int)(Screen.SCREEN_HEIGHT)); } + internal void FrameStart() + { + if ((MMU.PPUREG[1] & (PPU_SPDISP_BIT | PPU_BGDISP_BIT)) != 0) + { + MMU.loopy_v = MMU.loopy_t; + loopy_shift = MMU.loopy_x; + loopy_y = (ushort)((MMU.loopy_v & 0x7000) >> 12); + } + + if (lpScreen != null) + { + MemoryUtility.memset(lpScreen, 0x3F, (int)Screen.SCREEN_WIDTH); + } + if (lpColormode != null) + { + lpColormode[0] = 0; + } + } + + internal void ScanlineNext() + { + if ((MMU.PPUREG[1] & (PPU_BGDISP_BIT | PPU_SPDISP_BIT)) != 0) + { + if ((MMU.loopy_v & 0x7000) == 0x7000) + { + MMU.loopy_v &= 0x8FFF; + if ((MMU.loopy_v & 0x03E0) == 0x03A0) + { + MMU.loopy_v ^= 0x0800; + MMU.loopy_v &= 0xFC1F; + } + else + { + if ((MMU.loopy_v & 0x03E0) == 0x03E0) + { + MMU.loopy_v &= 0xFC1F; + } + else + { + MMU.loopy_v += 0x0020; + } + } + } + else + { + MMU.loopy_v += 0x1000; + } + loopy_y = (ushort)((MMU.loopy_v & 0x7000) >> 12); + } + } + + internal void ScanlineStart() + { + if ((MMU.PPUREG[1] & (PPU_BGDISP_BIT | PPU_SPDISP_BIT)) != 0) + { + MMU.loopy_v = (ushort)((MMU.loopy_v & 0xFBE0) | (MMU.loopy_t & 0x041F)); + loopy_shift = MMU.loopy_x; + loopy_y = (ushort)((MMU.loopy_v & 0x7000) >> 12); + nes.mapper.PPU_Latch((ushort)(0x2000 + (MMU.loopy_v & 0x0FFF))); + } + } + private enum Screen { SCREEN_WIDTH = 256 + 16,