public EmulatorSDL(string?cartridgePath, string?bootRomPath) { byte[]? cartridge = null; if (!string.IsNullOrEmpty(cartridgePath)) { cartridge = File.ReadAllBytes(cartridgePath); } byte[]? bootRom = null; if (!string.IsNullOrEmpty(bootRomPath)) { bootRom = File.ReadAllBytes(bootRomPath); } memory = new Memory(cartridge, bootRom); display = new SDLDisplay(); ppu = new PPU(memory, display); cpu = new CPU(memory, ppu); if (bootRom == null) { cpu.SetInitialStateAfterBootSequence(); } PrintDebugger(); printDebug = false; ppu.RenderEvent += RenderHandler; state = State.Running; Run(); }
public Render(PPU ppu, LCDCRegisters regs, byte[] vram) { this.VRAM = vram; this.LCDC = regs; this.ppu = ppu; this.rawPixels = new int[GB_SCREEN_WIDTH * GB_SCREEN_HEIGHT]; }
public NES(NesROM nesRom) { _nesRom = nesRom; CPU = new CPU(); InstructionSet = new InstructionSet(CPU); CPU.Reset(); PPU = new PPU(CPU); var mainWindowThread = new Thread(() => { var mainWindow = new MainWindow(CPU.Memory); mainWindow.ShowDialog(); }); mainWindowThread.Start(); var debuggerThread = new Thread(() => { Debugger = new Debugger(this); Debugger.Run(); }); debuggerThread.Start(); LoadDataToMemory(CPU.Memory, _nesRom.PRGROM, 0x8000); if (_nesRom.PRGROMSize == 0x4000) { LoadDataToMemory(CPU.Memory, _nesRom.PRGROM, 0xC000); } Execution = new AutoResetEvent(false); }
private void WriteBBus(int adr, int value) { if (adr < 0x34) { PPU.Write(adr, value); return; } if (adr >= 0x40 && adr < 0x80) { CatchUpApu(); APU.SpcReadPorts[adr & 0x3] = (byte)value; return; } switch (adr) { case 0x80: _ram[_ramAdr++] = (byte)value; _ramAdr &= 0x1ffff; return; case 0x81: _ramAdr = (_ramAdr & 0x1ff00) | value; return; case 0x82: _ramAdr = (_ramAdr & 0x100ff) | (value << 8); return; case 0x83: _ramAdr = (_ramAdr & 0x0ffff) | ((value & 1) << 16); return; } }
public Video_HiRes(TVFORMAT TvFormat, Control Surface, string pPath, int chrPages, PPU pp) { if (Surface == null) { return; } _Surface = Surface; oppu = pp; switch (TvFormat) { case TVFORMAT.NTSC: _ScanLines = 224; _FirstLinesTCut = 8; break; case TVFORMAT.PAL: _ScanLines = 240; _FirstLinesTCut = 0; break; } VideoModeSettings sett = new VideoModeSettings(); sett.Reload(); if (pPath != "") { ReadHiResPack(Path.GetDirectoryName(pPath) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(pPath), chrPages); } tilePalette = new int[3]; tileRow = new int[8]; MyNesDEBUGGER.WriteLine(this, "Video device " + @"""" + "Hi Res" + @"""" + " Ok !!", DebugStatus.Cool); }
public void DrawDisplay(PPU aPPU) { for (int i = 0; i < 144; ++i) { DrawDisplayLine(aPPU, i); } }
public CPUTests(ITestOutputHelper testOutputHelper) { this.testOutputHelper = testOutputHelper; memory = new Memory(new byte[] { IMMEDIATE_BYTE, (IMMEDIATE_WORD >> 8) & 0xFF }); display = new BlankDisplay(); ppu = new PPU(memory, display); loadUnit = A.Fake <LoadUnit>(); alu = A.Fake <ALU>(); miscUnit = A.Fake <MiscUnit>(); jumpUnit = A.Fake <JumpUnit>(); bitUnit = A.Fake <BitUnit>(); cpu = new CPU(memory, ppu, loadUnit, alu, miscUnit, jumpUnit, bitUnit) { A = 0x0A, B = 0x0B, C = 0x0C, D = 0x0D, E = 0x0E, H = 0xAA, L = 0xBB, PC = 0x00, SP = 0xFF }; memory.WriteByte(0xAABB, MEM_HL_BYTE); }
public void DrawTileset(PPU aPPU) { Color[] displayPixels = gbDisplay.Pixels; byte[] vram = aPPU.VRAM; int texWid = gbDisplay.TextureWidth; int aux = 0; for (int i = 0; i < 144; ++i) { for (int j = 0; j < 160; ++j) { aux = ((i / 8) * 20) + (j / 8); int tileIdx = (16 * aux); int lineDataL = vram[tileIdx + (2 * (i % 8))]; int lineDataH = vram[tileIdx + (2 * (i % 8)) + 1]; int colData = 1 << (7 - (j % 8)); int palIdx = (((lineDataL & colData) > 0) ? 1 : 0) + (((lineDataH & colData) > 0) ? 2 : 0); displayPixels[(i * texWid) + j] = m_LCDColor[palIdx]; } } }
public RegisterTests() { _mmu = new MMU(); _ppu = new PPU(_mmu); _input = new Input(_mmu); _cpu = new CPU(_mmu, _ppu, _input); }
public InstructionTests() { _mmu = new MMU(); _ppu = new PPU(_mmu); _input = new Input(_mmu); _cpu = new CPU(_mmu, _ppu, _input); }
private static Emulator Boot() { var ppuRegs = new PPURegisters(); var memoryBus = new MemoryBus(ppuRegs) { IsBootRomMapped = useBootRom }; //memoryBus.Attach(new GameLinkConsole()); var ppu = new PPU(ppuRegs, memoryBus); ppu.Boot(); var cpu = new CPU(new Registers(), memoryBus); if (!useBootRom) { cpu.BootWithoutBootRom(); } var rom = Cartridge.LoadFrom(romPath); memoryBus.Load(rom); var joypad = new Joypad(memoryBus.JoypadRegister); return(new Emulator(cpu, ppu, joypad)); }
public void Setup() { cart = new Cartridge(TestCartsPaths.tetris); clock = new Clock(); ppu = new PPU(clock); mmu = new MMU(cart, ppu, clock); reg = new Registers(mmu); cpu = new CPU(mmu, reg); }
public void Init(PPU ppu, BUS bus) { this.DISPCNT = new cDISPCNT(ppu); this.DISPSTAT = new cDISPSTAT(this.IF, ppu); this.VCOUNT = new cVCOUNT(this.IF, this.DISPSTAT); this.BGCNT = new cBGControl[4] { new cBGControl(ppu, 0xdfff), new cBGControl(ppu, 0xdfff), new cBGControl(ppu, 0xffff), new cBGControl(ppu, 0xffff) }; this.BGHOFS = new cBGScrolling[4] { new cBGScrolling(ppu, bus, true), new cBGScrolling(ppu, bus, false), new cBGScrolling(ppu, bus, true), new cBGScrolling(ppu, bus, false) }; this.BGVOFS = new cBGScrolling[4] { new cBGScrolling(ppu, bus, true), new cBGScrolling(ppu, bus, false), new cBGScrolling(ppu, bus, true), new cBGScrolling(ppu, bus, false) }; this.BG2X = new cReferencePoint(ppu, bus); this.BG2Y = new cReferencePoint(ppu, bus); this.BG3X = new cReferencePoint(ppu, bus); this.BG3Y = new cReferencePoint(ppu, bus); this.BG2PA = new cRotationScaling(bus, true); this.BG2PB = new cRotationScaling(bus, false); this.BG2PC = new cRotationScaling(bus, true); this.BG2PD = new cRotationScaling(bus, false); this.BG3PA = new cRotationScaling(bus, true); this.BG3PB = new cRotationScaling(bus, false); this.BG3PC = new cRotationScaling(bus, true); this.BG3PD = new cRotationScaling(bus, false); this.WINH = new cWindowDimensions[2] { new cWindowDimensions(ppu, bus, true), new cWindowDimensions(ppu, bus, false) }; this.WINV = new cWindowDimensions[2] { new cWindowDimensions(ppu, bus, true), new cWindowDimensions(ppu, bus, false) }; this.WININ = new cWindowControl(); this.WINOUT = new cWindowControl(); this.MOSAIC = new cMosaic(ppu); this.BLDCNT = new cBLDCNT(ppu); this.BLDALPHA = new cBLDALPHA(ppu); this.BLDY = new cBLDY(ppu); this.SIOCNT = new cSIOCNT(this.IF); this.KEYCNT = new cKeyInterruptControl(this); this.KEYINPUT = new cKeyInput(this.KEYCNT, this.IF); this.MasterUnusedRegister = new UnusedRegister(bus); }
public void Generate_Expected_Screen_Pixels_From_Known_Memory_Dump_With_Horizontally_And_Vertically_Positioned_Window() { byte[] allMemory = File.ReadAllBytes(Path.Combine("PPU", "Input", "mario_land_level_1_paused.dump")); var ppu = new PPU(allMemory); var actualPixels = ppu.ForceRenderScreen(); var expectedPixels = ImageHelper.LoadImageAsPaletteIndexedByteArray(Path.Combine("PPU", "Expected", "mario_land_level_1_paused_expected_screen.png")); AssertPixelsMatch(expectedPixels, actualPixels, width: PPU.ScreenWidthInPixels); }
public void Generate_Expected_Screen_Pixels_From_Known_Memory_Dump_With_Sprites_On_Top_Of_Fullscreen_Window() { byte[] allMemory = File.ReadAllBytes(Path.Combine("PPU", "Input", "pokemon_reds_room_start_menu.dump")); var ppu = new PPU(allMemory); var actualPixels = ppu.ForceRenderScreen(); var expectedPixels = ImageHelper.LoadImageAsPaletteIndexedByteArray(Path.Combine("PPU", "Expected", "pokemon_reds_room_start_menu_expected_screen.png")); AssertPixelsMatch(expectedPixels, actualPixels, width: PPU.ScreenWidthInPixels); }
public CPUforHelloWorld() { var rom = Resources.ResourceManager.GetObject("sample1"); var cartridge = new Cartridge(new MemoryStream((byte[])rom)); var ram = new RAM(0x0800); ppu = new PPU(cartridge); var bus = new CpuBus(ram, ppu, cartridge); cpu = new CPU(bus); }
public void Generate_Blank_Screen_When_LCD_Is_Disabled() { byte[] allMemory = File.ReadAllBytes(Path.Combine("PPU", "Input", "mario_land_level_1_paused.dump")); var ppu = new PPU(allMemory); ppu.Registers.LCDControl.Enabled = false; var actualPixels = ppu.ForceRenderScreen(); var expectedPixels = new byte[PPU.ScreenWidthInPixels * PPU.ScreenHeightInPixels]; AssertPixelsMatch(expectedPixels, actualPixels, width: PPU.ScreenWidthInPixels); }
public TestEmulator(string romPath, ushort stopAddress) { this.stopAddress = stopAddress; byte[] cartridge = File.ReadAllBytes(romPath); memory = new Memory(cartridge); display = new BlankDisplay(); ppu = new PPU(memory, display); cpu = new CPU(memory, ppu); cpu.SetInitialStateAfterBootSequence(); }
public GameBoyEmu(uint width, uint height, uint x = 0, uint y = 0) : base("GameBoyEmu", width, height, x, y) { Rom = Files.TetrisRom; mmu = new MMU(); cpu = new CPU(mmu); ppu = new PPU(); timer = new TIMER(); joypad = new JOYPAD(); mmu.loadGamePak(Rom); }
private static void Start(string romPath) { var ppuRegs = new PPURegisters(); var memoryBus = new MemoryBus(ppuRegs); ppu = new PPU(ppuRegs, memoryBus); cpu = new CPU(new Registers(), memoryBus); cpu.BootWithoutBootRom(); var rom = Cartridge.LoadFrom(romPath); memoryBus.Load(rom); }
public void LoadROM(string fileName) { FileName = fileName; byte[] data = File.ReadAllBytes(FileName); LoadRom(data); GameName = ROM.Header.Name; Reset1(); CPU.Reset(); PPU.Reset(); APU.Reset(); Reset2(); Run(); }
public static void Main() { var ppu = new PPU(File.ReadAllBytes(memoryDumpPath)); Console.WriteLine(ppu.Registers.LCDControl + Environment.NewLine); var tilesetPixels = ppu.RenderTileSet(); var bgMapPixels = ppu.RenderBackgroundMap(); var windowPixels = ppu.RenderWindow(); var spritePixels = ppu.RenderSprites(); var screenPixels = ppu.ForceRenderScreen(); WritePixelDataFiles(tilesetPixels, bgMapPixels, windowPixels, spritePixels, screenPixels); }
public override void InitializeMemoryMap(PPU ppu) { ppu.MapReadHandler(0x0000, 0x1FFF, address => { var bank = address / 0x1000; var ret = _chrROM[_chrBankOffsets[bank, _latches[bank].AsByte()] + address % 0x1000]; if ((address & 0x08) > 0) { GetLatch(address, out uint latch, out bool?on); if (on != null) { _latches[latch] = (bool)on; } }
public Gameboy(ConstructAudioEmitter constructor) { ConstructEmitter = constructor; Mmu = new MMU(this); Ppu = new PPU(this); Apu = new APU(this); Input = new Input(this); Timer = new Timer(this); Cpu = new CPU(this); Dma = new DMA(this); LinkCable = new LinkCable(this); Reset(); }
public void Generate_Expected_Screen_Pixels_From_Known_Memory_Dump_With_Nonstandard_Background_Palette() { //most games use a background palette of 0xE4, which maps the background colors 1:1 //(e.g. color #3 is 11 => black, color #2 is 10 => dark gray, color #1 is 01 => light gray, color #0 is 00 => white) //so they appear correct even without using the background color palette //Donkey Kong Land 2 is one game that uses a different background palette, so test that it renders as expected byte[] allMemory = File.ReadAllBytes(Path.Combine("PPU", "Input", "donkey_kong_land_2_level_1.dump")); var ppu = new PPU(allMemory); var actualPixels = ppu.ForceRenderScreen(); var expectedPixels = ImageHelper.LoadImageAsPaletteIndexedByteArray(Path.Combine("PPU", "Expected", "donkey_kong_land_2_level_1_expected_screen.png")); AssertPixelsMatch(expectedPixels, actualPixels, width: PPU.ScreenWidthInPixels); }
public void Generate_Expected_Background_Map_Pixels_From_Known_VRAM_Dump_Using_Unsigned_Tile_Numbers() { var vram = Memory.FromFile(Path.Combine("PPU", "Input", "tetris_title_screen.vram.dump")); var regs = new PPURegisters(lcdc: 0xD3, bgPalette: 0xE4); var memBus = new MemoryBus(regs) { VideoMemory = vram }; var ppu = new PPU(regs, memBus); ppu.TileSet.UpdateFrom(vram); var actualPixels = ppu.RenderBackgroundMap(); var expectedPixels = ImageHelper.LoadImageAsPaletteIndexedByteArray(Path.Combine("PPU", "Expected", "tetris_title_screen_expected_bgmap.png")); AssertPixelsMatch(expectedPixels, actualPixels, width: 256); }
public void Generate_Blank_Background_Map_Pixels_When_Background_Map_Drawing_Is_Disabled() { var vram = Memory.FromFile(Path.Combine("PPU", "Input", "pokemon_reds_room.vram.dump")); var regs = new PPURegisters(lcdc: 0xE0); //LCDC bit 0 = 0 => background is disabled var memBus = new MemoryBus(regs) { VideoMemory = vram }; var ppu = new PPU(regs, memBus); Assert.IsFalse(ppu.Registers.LCDControl.BackgroundDisplayEnabled); var actualPixels = ppu.RenderBackgroundMap(); var expectedPixels = new byte[TileMap.WidthInPixels * TileMap.HeightInPixels]; AssertPixelsMatch(expectedPixels, actualPixels, width: 256); }
public void Generate_Blank_Sprite_Pixels_When_Sprite_Drawing_Is_Disabled() { var vram = Memory.FromFile(Path.Combine("PPU", "Input", "pokemon_reds_room.vram.dump")); var oam = Memory.FromFile(Path.Combine("PPU", "Input", "pokemon_reds_room.oam.dump")); var regs = new PPURegisters(lcdc: 0xE3, spritePalette0: 0xE4, spritePalette1: 0xE4); var memBus = new MemoryBus(regs) { VideoMemory = vram, ObjectAttributeMemory = oam }; var ppu = new PPU(regs, memBus); ppu.Registers.LCDControl.SpriteDisplayEnabled = false; var actualPixels = ppu.RenderSprites(); var expectedPixels = new byte[PPU.ScreenWidthInPixels * PPU.ScreenHeightInPixels]; AssertPixelsMatch(expectedPixels, actualPixels, width: PPU.ScreenWidthInPixels); }
public void Generate_Expected_Window_Pixels_From_Known_VRAM_Dump_Using_Signed_Tile_Numbers() { var vram = Memory.FromFile(Path.Combine("PPU", "Input", "links_awakening_you_are_on_koholint_island.vram.dump")); var regs = new PPURegisters(lcdc: 0xE7, bgPalette: 0xE4); var memBus = new MemoryBus(regs) { VideoMemory = vram }; var ppu = new PPU(regs, memBus); ppu.TileSet.UpdateFrom(vram); var actualPixels = ppu.RenderWindow(); var expectedPixels = ImageHelper.LoadImageAsPaletteIndexedByteArray(Path.Combine("PPU", "Expected", "links_awakening_you_are_on_koholint_island_expected_window.png")); AssertPixelsMatch(expectedPixels, actualPixels, width: 256); }
public void Generate_Blank_Window_Pixels_When_Window_Drawing_Is_Disabled() { var vram = Memory.FromFile(Path.Combine("PPU", "Input", "links_awakening_you_are_on_koholint_island.vram.dump")); var regs = new PPURegisters(lcdc: 0xD7); //LCDC bit 5 = 0 => window is disabled var memBus = new MemoryBus(regs) { VideoMemory = vram }; var ppu = new PPU(regs, memBus); Assert.IsFalse(ppu.Registers.LCDControl.WindowDisplayEnabled); var actualPixels = ppu.RenderWindow(); var expectedPixels = new byte[TileMap.WidthInPixels * TileMap.HeightInPixels]; AssertPixelsMatch(expectedPixels, actualPixels, width: 256); }
public Video(PPU thePPU) { //Initialize video emulation framework myPPU = thePPU; //END Initialize video emulation framework }