예제 #1
0
        private void SyncState(Serializer ser)
        {
            byte[] core = null;
            if (ser.IsWriter)
            {
                var ms = new MemoryStream();
                ms.Close();
                core = ms.ToArray();
            }
            Cpu.SyncState(ser);

            ser.BeginSection("SMS");
            Vdp.SyncState(ser);
            PSG.SyncState(ser);
            ser.Sync("RAM", ref SystemRam, false);
            ser.Sync("RomBank0", ref RomBank0);
            ser.Sync("RomBank1", ref RomBank1);
            ser.Sync("RomBank2", ref RomBank2);
            ser.Sync("RomBank3", ref RomBank3);
            ser.Sync("Port01", ref Port01);
            ser.Sync("Port02", ref Port02);
            ser.Sync("Port3E", ref Port3E);
            ser.Sync("Port3F", ref Port3F);
            ser.Sync("Paddle1High", ref Paddle1High);
            ser.Sync("Paddle2High", ref Paddle2High);
            ser.Sync("LatchLightPhaser", ref LatchLightPhaser);

            if (SaveRAM != null)
            {
                ser.Sync("SaveRAM", ref SaveRAM, false);
                ser.Sync("SaveRamBank", ref SaveRamBank);
            }

            if (ExtRam != null)
            {
                ser.Sync("ExtRAM", ref ExtRam, true);
            }

            if (HasYM2413)
            {
                YM2413.SyncState(ser);
            }

            if (EEPROM != null)
            {
                EEPROM.SyncState(ser);
            }

            ser.Sync("Frame", ref _frame);
            ser.Sync("LagCount", ref _lagCount);
            ser.Sync("IsLag", ref _isLag);

            ser.EndSection();

            if (ser.IsReader)
            {
                SyncAllByteArrayDomains();
            }
        }
예제 #2
0
        public bool FrameAdvance(IController controller, bool render, bool rendersound)
        {
            _controller = controller;
            _lagged     = true;
            _frame++;
            PSG.BeginFrame(Cpu.TotalExecutedCycles);

            if (!IsGameGear)
            {
                PSG.StereoPanning = Settings.ForceStereoSeparation ? ForceStereoByte : (byte)0xFF;
            }

            if (Tracer.Enabled)
            {
                Cpu.TraceCallback = s => Tracer.Put(s);
            }
            else
            {
                Cpu.TraceCallback = null;
            }

            if (IsGameGear_C == false)
            {
                Cpu.NonMaskableInterrupt = controller.IsPressed("Pause");
            }
            else if (!IsGameGear && IsGameGear_C)
            {
                Cpu.NonMaskableInterrupt = controller.IsPressed("P1 Start");
            }

            if (IsGame3D && Settings.Fix3D)
            {
                Vdp.ExecFrame((Frame & 1) == 0);
            }
            else
            {
                Vdp.ExecFrame(render);
            }

            PSG.EndFrame(Cpu.TotalExecutedCycles);
            if (_lagged)
            {
                _lagCount++;
                _isLag = true;
            }
            else
            {
                _isLag = false;
            }

            return(true);
        }
예제 #3
0
        private void SyncState(Serializer ser)
        {
            ser.BeginSection("SMS");
            Cpu.SyncState(ser);
            Vdp.SyncState(ser);
            PSG.SyncState(ser);
            ser.Sync("RAM", ref SystemRam, false);
            ser.Sync("RomBank0", ref RomBank0);
            ser.Sync("RomBank1", ref RomBank1);
            ser.Sync("RomBank2", ref RomBank2);
            ser.Sync("RomBank3", ref RomBank3);
            ser.Sync("Port01", ref Port01);
            ser.Sync("Port02", ref Port02);
            ser.Sync("Port3E", ref Port3E);
            ser.Sync("Port3F", ref Port3F);

            if (SaveRAM != null)
            {
                ser.Sync("SaveRAM", ref SaveRAM, false);
                ser.Sync("SaveRamBank", ref SaveRamBank);
            }

            if (ExtRam != null)
            {
                ser.Sync("ExtRAM", ref ExtRam, true);
            }

            if (HasYM2413)
            {
                YM2413.SyncState(ser);
            }

            ser.Sync("Frame", ref frame);
            ser.Sync("LagCount", ref _lagCount);
            ser.Sync("IsLag", ref _isLag);

            ser.EndSection();

            if (ser.IsReader)
            {
                SyncAllByteArrayDomains();
            }
        }
예제 #4
0
        public void FrameAdvance(IController controller, bool render, bool rendersound)
        {
            _controller = controller;
            _lagged     = true;
            _frame++;
            PSG.BeginFrame(Cpu.TotalExecutedCycles);
            Cpu.Debug = Tracer.Enabled;
            if (!IsGameGear)
            {
                PSG.StereoPanning = Settings.ForceStereoSeparation ? ForceStereoByte : (byte)0xFF;
            }

            if (Cpu.Debug && Cpu.Logger == null)             // TODO, lets not do this on each frame. But lets refactor CoreComm/CoreComm first
            {
                Cpu.Logger = s => Tracer.Put(s);
            }

            if (IsGameGear == false)
            {
                Cpu.NonMaskableInterrupt = controller.IsPressed("Pause");
            }

            if (IsGame3D && Settings.Fix3D)
            {
                Vdp.ExecFrame((Frame & 1) == 0);
            }
            else
            {
                Vdp.ExecFrame(render);
            }

            PSG.EndFrame(Cpu.TotalExecutedCycles);
            if (_lagged)
            {
                _lagCount++;
                _isLag = true;
            }
            else
            {
                _isLag = false;
            }
        }
예제 #5
0
        private unsafe void DrawBG(int *pal)
        {
            int bgHeight = Vdp.FrameHeight == 192 ? 224 : 256;
            int maxTile  = bgHeight * 4;

            if (bgHeight != bmpViewBG.Bmp.Height)
            {
                bmpViewBG.Height = bgHeight;
                bmpViewBG.ChangeBitmapSize(256, bgHeight);
            }

            var  lockData = bmpViewBG.Bmp.LockBits(new Rectangle(0, 0, 256, bgHeight), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            int *dest     = (int *)lockData.Scan0;
            int  pitch    = lockData.Stride / sizeof(int);

            fixed(byte *src = Vdp.PatternBuffer)
            fixed(byte *vram = Vdp.VRAM)
            {
                short *map = (short *)(vram + Vdp.CalcNameTableBase());

                for (int tile = 0; tile < maxTile; tile++)
                {
                    short bgent    = *map++;
                    bool  hFlip    = (bgent & 1 << 9) != 0;
                    bool  vFlip    = (bgent & 1 << 10) != 0;
                    int * tpal     = pal + ((bgent & 1 << 11) >> 7);
                    int   srcAddr  = (bgent & 511) * 64;
                    int   tx       = tile & 31;
                    int   ty       = tile >> 5;
                    int   destAddr = ty * 8 * pitch + tx * 8;
                    Draw8x8hv(src + srcAddr, dest + destAddr, pitch, tpal, hFlip, vFlip);
                }
            }
            bmpViewBG.Bmp.UnlockBits(lockData);
            bmpViewBG.Refresh();
        }
예제 #6
0
        private void SyncState(Serializer ser)
        {
            byte[] core = null;
            if (ser.IsWriter)
            {
                using var ms = new MemoryStream();
                ms.Close();
                core = ms.ToArray();
            }

            ser.BeginSection(nameof(SMS));
            Cpu.SyncState(ser);
            Vdp.SyncState(ser);
            PSG.SyncState(ser);
            ser.Sync("RAM", ref SystemRam, false);
            ser.Sync(nameof(RomBank0), ref RomBank0);
            ser.Sync(nameof(RomBank1), ref RomBank1);
            ser.Sync(nameof(RomBank2), ref RomBank2);
            ser.Sync(nameof(RomBank3), ref RomBank3);
            ser.Sync(nameof(Bios_bank), ref Bios_bank);
            ser.Sync(nameof(Port01), ref Port01);
            ser.Sync(nameof(Port02), ref Port02);
            ser.Sync(nameof(Port03), ref Port03);
            ser.Sync(nameof(Port04), ref Port04);
            ser.Sync(nameof(Port05), ref Port05);
            ser.Sync(nameof(Port3E), ref Port3E);
            ser.Sync(nameof(Port3F), ref Port3F);
            ser.Sync(nameof(Controller1SelectHigh), ref Controller1SelectHigh);
            ser.Sync(nameof(Controller2SelectHigh), ref Controller2SelectHigh);
            ser.Sync(nameof(LatchLightPhaser), ref LatchLightPhaser);
            ser.Sync(nameof(start_pressed), ref start_pressed);
            ser.Sync(nameof(cntr_rd_0), ref cntr_rd_0);
            ser.Sync(nameof(cntr_rd_1), ref cntr_rd_1);
            ser.Sync(nameof(cntr_rd_2), ref cntr_rd_2);
            ser.Sync(nameof(p3_write), ref p3_write);
            ser.Sync(nameof(p4_read), ref p4_read);
            ser.Sync(nameof(stand_alone), ref stand_alone);
            ser.Sync(nameof(disablePSG), ref disablePSG);
            ser.Sync(nameof(sampleclock), ref sampleclock);
            ser.Sync(nameof(old_s_L), ref old_s_L);
            ser.Sync(nameof(old_s_R), ref old_s_R);

            if (SaveRAM != null)
            {
                ser.Sync(nameof(SaveRAM), ref SaveRAM, false);
            }

            ser.Sync(nameof(SaveRamBank), ref SaveRamBank);

            if (ExtRam != null)
            {
                ser.Sync("ExtRAM", ref ExtRam, true);
            }

            if (HasYM2413)
            {
                YM2413.SyncState(ser);
            }

            EEPROM?.SyncState(ser);

            ser.Sync("Frame", ref _frame);
            ser.Sync("LagCount", ref _lagCount);
            ser.Sync("IsLag", ref _isLag);

            ser.EndSection();

            if (ser.IsReader)
            {
                SyncAllByteArrayDomains();
            }
        }
예제 #7
0
        public bool FrameAdvance(IController controller, bool render, bool rendersound)
        {
            _controller = controller;
            _lagged     = true;
            _frame++;

            if (!IsGameGear)
            {
                PSG.Set_Panning(Settings.ForceStereoSeparation ? ForceStereoByte : (byte)0xFF);
            }

            if (Tracer.Enabled)
            {
                Cpu.TraceCallback = s => Tracer.Put(s);
            }
            else
            {
                Cpu.TraceCallback = null;
            }

            if (IsGameGear_C == false)
            {
                Cpu.NonMaskableInterrupt = controller.IsPressed("Pause");
            }
            else if (!IsGameGear && IsGameGear_C)
            {
                Cpu.NonMaskableInterrupt = controller.IsPressed("P1 Start");
            }

            if (IsGame3D && Settings.Fix3D)
            {
                render = ((Frame & 1) == 0) & render;
            }

            int scanlinesPerFrame = Vdp.DisplayType == DisplayType.NTSC ? 262 : 313;

            Vdp.SpriteLimit = Settings.SpriteLimit;
            for (int i = 0; i < scanlinesPerFrame; i++)
            {
                Vdp.ScanLine = i;

                Vdp.RenderCurrentScanline(render);

                Vdp.ProcessFrameInterrupt();
                Vdp.ProcessLineInterrupt();
                ProcessLineControls();

                for (int j = 0; j < Vdp.IPeriod; j++)
                {
                    Cpu.ExecuteOne();

                    PSG.generate_sound();

                    s_L = PSG.current_sample_L;
                    s_R = PSG.current_sample_R;

                    if (s_L != old_s_L)
                    {
                        blip_L.AddDelta(sampleclock, s_L - old_s_L);
                        old_s_L = s_L;
                    }

                    if (s_R != old_s_R)
                    {
                        blip_R.AddDelta(sampleclock, s_R - old_s_R);
                        old_s_R = s_R;
                    }

                    sampleclock++;
                }

                if (Vdp.ScanLine == scanlinesPerFrame - 1)
                {
                    Vdp.ProcessGGScreen();
                    Vdp.ProcessOverscan();
                }
            }

            if (_lagged)
            {
                _lagCount++;
                _isLag = true;
            }
            else
            {
                _isLag = false;
            }

            return(true);
        }