Esempio n. 1
0
        public void WriteMemory(ushort addr, byte value, bool poke)
        {
            var maskedAddr = (ushort)(addr & 0x3f);

            if (!poke)
            {
                BusState = value;
            }

            if (maskedAddr == 0x00)             // VSYNC
            {
                if ((value & 0x02) != 0)
                {
                    // Frame is complete, output to buffer
                    _vsyncEnabled = true;
                }
                else if (_vsyncEnabled)
                {
                    // When VSYNC is disabled, this will be the first line of the new frame

                    // write to frame buffer
                    OutputFrame(_currentScanLine);

                    New_Frame = true;

                    // Clear all from last frame
                    _currentScanLine = 0;

                    // Frame is done
                    _vsyncEnabled = false;

                    // Do not reset hsync, since we're on the first line of the new frame
                    // hsyncCnt = 0;
                }
            }
            else if (maskedAddr == 0x01)             // VBLANK
            {
                _vblankDelay = 1;
                _vblankValue = value;
                _capCharging = (value & 0x80) == 0;
                if ((value & 0x80) == 0)
                {
                    _capChargeStart = _core.Cpu.TotalExecutedCycles;
                }
            }
            else if (maskedAddr == 0x02)             // WSYNC
            {
                // Halt the CPU until we reach hblank
                _core.Cpu.RDY = false;
            }
            else if (maskedAddr == 0x04)             // NUSIZ0
            {
                _nusiz0Delay = 1;
                _nusiz0Val   = value;
            }
            else if (maskedAddr == 0x05)             // NUSIZ1
            {
                _nusiz1Delay = 1;
                _nusiz1Val   = value;
            }
            else if (maskedAddr == 0x06)             // COLUP0
            {
                _player0.Color = (byte)(value & 0xFE);
            }
            else if (maskedAddr == 0x07)             // COLUP1
            {
                _player1.Color = (byte)(value & 0xFE);
            }
            else if (maskedAddr == 0x08)             // COLUPF
            {
                _playField.PfColor = (byte)(value & 0xFE);
            }
            else if (maskedAddr == 0x09)             // COLUBK
            {
                _playField.BkColor = (byte)(value & 0xFE);
            }
            else if (maskedAddr == 0x0A)             // CTRLPF
            {
                _playField.Reflect  = (value & 0x01) != 0;
                _playField.Score    = (value & 0x02) != 0;
                _playField.Priority = (value & 0x04) != 0;

                _ball.Size = (byte)((value & 0x30) >> 4);
            }
            else if (maskedAddr == 0x0B)             // REFP0
            {
                _player0.Reflect = (value & 0x08) != 0;
            }
            else if (maskedAddr == 0x0C)             // REFP1
            {
                _player1.Reflect = (value & 0x08) != 0;
            }
            else if (maskedAddr == 0x0D)             // PF0
            {
                _pf0Update     = value;
                _pf0Updater    = true;
                _pf0DelayClock = 0;
                if (((_hsyncCnt / 3) & 3) == 0)
                {
                    _pf0MaxDelay = 4;
                }

                if (((_hsyncCnt / 3) & 3) == 1)
                {
                    _pf0MaxDelay = 5;
                }

                if (((_hsyncCnt / 3) & 3) == 2)
                {
                    _pf0MaxDelay = 2;
                }

                if (((_hsyncCnt / 3) & 3) == 3)
                {
                    _pf0MaxDelay = 3;
                }
            }
            else if (maskedAddr == 0x0E)             // PF1
            {
                _pf1Update     = value;
                _pf1Updater    = true;
                _pf1DelayClock = 0;
                if (((_hsyncCnt / 3) & 3) == 0)
                {
                    _pf1MaxDelay = 4;
                }

                if (((_hsyncCnt / 3) & 3) == 1)
                {
                    _pf1MaxDelay = 5;
                }

                if (((_hsyncCnt / 3) & 3) == 2)
                {
                    _pf1MaxDelay = 2;
                }

                if (((_hsyncCnt / 3) & 3) == 3)
                {
                    _pf1MaxDelay = 3;
                }
            }
            else if (maskedAddr == 0x0F)             // PF2
            {
                _pf2Update     = value;
                _pf2Updater    = true;
                _pf2DelayClock = 0;
                if (((_hsyncCnt / 3) & 3) == 0)
                {
                    _pf2MaxDelay = 4;
                }

                if (((_hsyncCnt / 3) & 3) == 1)
                {
                    _pf2MaxDelay = 5;
                }

                if (((_hsyncCnt / 3) & 3) == 2)
                {
                    _pf2MaxDelay = 2;
                }

                if (((_hsyncCnt / 3) & 3) == 3)
                {
                    _pf2MaxDelay = 3;
                }
            }
            else if (maskedAddr == 0x10)             // RESP0
            {
                // RESP delays draw signal clocking
                _player0.Resp_check();

                // Resp depends on HMOVE
                if (!_hmove.LateHBlankReset)
                {
                    _player0.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 67)
                    {
                        _player0.HPosCnt = 160 - 3;
                    }
                }
                else
                {
                    _player0.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 75)
                    {
                        _player0.HPosCnt = 160 - 3;
                    }
                }
            }
            else if (maskedAddr == 0x11)             // RESP1
            {
                // RESP delays draw signal clocking
                _player1.Resp_check();

                // RESP depends on HMOVE
                if (!_hmove.LateHBlankReset)
                {
                    _player1.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 67)
                    {
                        _player1.HPosCnt = 160 - 3;
                    }
                }
                else
                {
                    _player1.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 75)
                    {
                        _player1.HPosCnt = 160 - 3;
                    }
                }
            }
            else if (maskedAddr == 0x12)             // RESM0
            {
                // RESP delays draw signal clocking
                _player0.Missile.Resp_check();

                if (!_hmove.LateHBlankReset)
                {
                    _player0.Missile.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 67)
                    {
                        _player0.Missile.HPosCnt = 160 - 3;
                    }
                }
                else
                {
                    _player0.Missile.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 75)
                    {
                        _player0.Missile.HPosCnt = 160 - 3;
                    }
                }
            }
            else if (maskedAddr == 0x13)             // RESM1
            {
                // RESP delays draw signal clocking
                _player1.Missile.Resp_check();

                if (!_hmove.LateHBlankReset)
                {
                    _player1.Missile.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 67)
                    {
                        _player1.Missile.HPosCnt = 160 - 3;
                    }
                }
                else
                {
                    _player1.Missile.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 75)
                    {
                        _player1.Missile.HPosCnt = 160 - 3;
                    }
                }
            }
            else if (maskedAddr == 0x14)             // RESBL
            {
                _ball.Resp_check();

                if (!_hmove.LateHBlankReset)
                {
                    _ball.HPosCnt = (byte)(_hsyncCnt < 68 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 67)
                    {
                        _ball.HPosCnt = 160 - 3;
                    }
                }
                else
                {
                    _ball.HPosCnt = (byte)(_hsyncCnt < 76 ? 160 - 2 : 160 - 4);
                    if (_hsyncCnt == 75)
                    {
                        _ball.HPosCnt = 160 - 3;
                    }
                }
            }
            else if (maskedAddr == 0x15)             // AUDC0
            {
                AUD.AUDC_L = (byte)(value & 15);
            }
            else if (maskedAddr == 0x16)             // AUDC1
            {
                AUD.AUDC_R = (byte)(value & 15);
            }
            else if (maskedAddr == 0x17)             // AUDF0
            {
                AUD.AUDF_L = (byte)((value & 31) + 1);
            }
            else if (maskedAddr == 0x18)             // AUDF1
            {
                AUD.AUDF_R = (byte)((value & 31) + 1);
            }
            else if (maskedAddr == 0x19)             // AUDV0
            {
                AUD.AUDV_L = (byte)(value & 15);
            }
            else if (maskedAddr == 0x1A)             // AUDV1
            {
                AUD.AUDV_R = (byte)(value & 15);
            }
            else if (maskedAddr == 0x1B)             // GRP0
            {
                _prg0Val   = value;
                _prg0Delay = 1;
            }
            else if (maskedAddr == 0x1C)             // GRP1
            {
                _prg1Val   = value;
                _prg1Delay = 1;
            }
            else if (maskedAddr == 0x1D)             // ENAM0
            {
                _enam0Val   = (value & 0x02) != 0;
                _enam0Delay = 1;
            }
            else if (maskedAddr == 0x1E)             // ENAM1
            {
                _enam1Val   = (value & 0x02) != 0;
                _enam1Delay = 1;
            }
            else if (maskedAddr == 0x1F)             // ENABL
            {
                _enambVal   = (value & 0x02) != 0;
                _enambDelay = 1;
            }
            else if (maskedAddr == 0x20)             // HMP0
            {
                _hmp0Val   = (byte)((value & 0xF0) >> 4);
                _hmp0Delay = 1;
            }
            else if (maskedAddr == 0x21)             // HMP1
            {
                _hmp1Val   = (byte)((value & 0xF0) >> 4);
                _hmp1Delay = 1;
            }
            else if (maskedAddr == 0x22)             // HMM0
            {
                _hmm0Val   = (byte)((value & 0xF0) >> 4);
                _hmm0Delay = 1;
            }
            else if (maskedAddr == 0x23)             // HMM1
            {
                _hmm1Val   = (byte)((value & 0xF0) >> 4);
                _hmm1Delay = 1;
            }
            else if (maskedAddr == 0x24)             // HMBL
            {
                _hmbVal   = (byte)((value & 0xF0) >> 4);
                _hmbDelay = 1;
            }
            else if (maskedAddr == 0x25)             // VDELP0
            {
                _player0.Delay = (value & 0x01) != 0;
            }
            else if (maskedAddr == 0x26)             // VDELP1
            {
                _player1.Delay = (value & 0x01) != 0;
            }
            else if (maskedAddr == 0x27)             // VDELBL
            {
                _ball.Delay = (value & 0x01) != 0;
            }
            else if (maskedAddr == 0x28)             // RESMP0
            {
                _player0.Missile.ResetToPlayer = (value & 0x02) != 0;
            }
            else if (maskedAddr == 0x29)             // RESMP1
            {
                _player1.Missile.ResetToPlayer = (value & 0x02) != 0;
            }
            else if (maskedAddr == 0x2A)             // HMOVE
            {
                _hmove.HMoveEnabled  = true;
                hmove_cnt_up         = true;
                _hmove.HMoveDelayCnt = 0;
            }
            else if (maskedAddr == 0x2B)             // HMCLR
            {
                _hmClrDelay = 1;
            }
            else if (maskedAddr == 0x2C)             // CXCLR
            {
                _player0.Collisions         = 0;
                _player0.Missile.Collisions = 0;
                _player1.Collisions         = 0;
                _player1.Missile.Collisions = 0;
                _ball.Collisions            = 0;
            }
        }