Exemple #1
0
        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();
        }
Exemple #2
0
 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];
 }
Exemple #3
0
        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;
            }
        }
Exemple #5
0
        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);
        }
Exemple #6
0
 public void DrawDisplay(PPU aPPU)
 {
     for (int i = 0; i < 144; ++i)
     {
         DrawDisplayLine(aPPU, i);
     }
 }
Exemple #7
0
        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);
        }
Exemple #8
0
                    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];
                            }
                        }
                    }
Exemple #9
0
 public RegisterTests()
 {
     _mmu = new MMU();
     _ppu = new PPU(_mmu);
     _input = new Input(_mmu);
     _cpu = new CPU(_mmu, _ppu, _input);
 }
Exemple #10
0
 public InstructionTests()
 {
     _mmu   = new MMU();
     _ppu   = new PPU(_mmu);
     _input = new Input(_mmu);
     _cpu   = new CPU(_mmu, _ppu, _input);
 }
Exemple #11
0
        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));
        }
Exemple #12
0
 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);
 }
Exemple #13
0
        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);
        }
Exemple #14
0
        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);
        }
Exemple #15
0
        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);
        }
Exemple #16
0
        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);
        }
Exemple #17
0
        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);
        }
Exemple #18
0
        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);
        }
Exemple #20
0
        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();
 }
Exemple #22
0
        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);
        }
Exemple #23
0
        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;
                    }
                }
Exemple #24
0
        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();
        }
Exemple #25
0
        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);
        }
Exemple #26
0
        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);
        }
Exemple #27
0
        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);
        }
Exemple #28
0
        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);
        }
Exemple #29
0
        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);
        }
Exemple #30
0
        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);
        }
Exemple #31
0
 public Video(PPU thePPU)
 {
     //Initialize video emulation framework
     myPPU = thePPU;
     //END Initialize video emulation framework
 }