Exemple #1
0
        /// <summary>
        /// Reads the memory at the specified address
        /// </summary>
        /// <param name="addr">Memory address</param>
        /// <param name="noContention">Indicates non-contended read operation</param>
        /// <returns>Byte read from the memory</returns>
        public override byte Read(ushort addr, bool noContention = false)
        {
            var  memIndex = addr & 0x3FFF;
            byte memValue;

            switch (addr & 0xC000)
            {
            case 0x0000:
                return(CurrentRomPage[memIndex]);

            case 0x4000:
                memValue = RamBanks[5][memIndex];
                if (noContention || _screenDevice == null)
                {
                    return(memValue);
                }
                _cpu?.Delay(_screenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                return(memValue);

            case 0x8000:
                return(RamBanks[2][memIndex]);

            default:
                memValue = RamBanks[_currentSlot3Bank][memIndex];
                if ((_currentSlot3Bank & 0x01) == 0)
                {
                    return(memValue);
                }

                // --- Bank 1, 3, 5, and 7 are contended
                _cpu?.Delay(_screenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                return(memValue);
            }
        }
Exemple #2
0
        /// <summary>
        /// Reads the memory at the specified address
        /// </summary>
        /// <param name="addr">Memory address</param>
        /// <returns>Byte read from the memory</returns>
        public byte Read(ushort addr)
        {
            var memIndex = addr & 0x3FFF;

            switch (addr & 0xC000)
            {
            case 0x0000:
                return(_currentRomPage[memIndex]);

            case 0x4000:
                if (_screenDevice != null)
                {
                    _cpu?.Delay(_screenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                }
                return(_ramBanks[5][memIndex]);

            case 0x8000:
                return(_ramBanks[2][memIndex]);

            default:
                if ((_currentSlot3Bank & 0x01) != 0)
                {
                    // --- Bank 1, 3, 5, and 7 are contended
                    _cpu?.Delay(_screenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                }
                return(_ramBanks[_currentSlot3Bank][memIndex]);
            }
        }
Exemple #3
0
        /// <summary>
        /// Reads the memory at the specified address
        /// </summary>
        /// <param name="addr">Memory address</param>
        /// <returns>Byte read from the memory</returns>
        public byte Read(ushort addr)
        {
            var value = _memory[addr];

            if ((addr & 0xC000) == 0x4000)
            {
                _cpu.Delay(_screenDevice.GetContentionValue(HostVm.CurrentFrameTact));
            }
            return(value);
        }
 /// <summary>
 /// Emulates memory contention
 /// </summary>
 /// <param name="addr">Contention address</param>
 public virtual void ContentionWait(ushort addr)
 {
     if ((addr & 0xC000) == 0x4000)
     {
         var delay = ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact);
         Cpu?.Delay(delay);
     }
 }
Exemple #5
0
        /// <summary>
        /// Reads the port with the specified address
        /// </summary>
        /// <param name="addr">Port address</param>
        /// <returns>Byte read from the port</returns>
        public virtual byte OnReadPort(ushort addr)
        {
            // --- Apply I/O contention delay
            var lowBit  = (addr & 0x0001) != 0;
            var ulaHigh = (addr & 0xc000) == 0x4000;

            if (ulaHigh)
            {
                Cpu.Delay(ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact - 1));
            }
            else
            {
                if (!lowBit)
                {
                    Cpu.Delay(ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                }
            }
            return(0xFF);
        }
Exemple #6
0
        /// <summary>
        /// Applies the delay according to the current frame tact
        /// </summary>
        protected void ApplyDelay()
        {
            if (HostVm == null)
            {
                return;
            }
            var delay = ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact);

            Cpu.Delay(delay);
            HostVm.ContentionAccumulated += delay;
        }
Exemple #7
0
        /// <summary>
        /// Reads the memory at the specified address
        /// </summary>
        /// <param name="addr">Memory address</param>
        /// <param name="noContention">Indicates non-contended read operation</param>
        /// <returns>Byte read from the memory</returns>
        public override byte Read(ushort addr, bool noContention = false)
        {
            var  memIndex = addr & 0x3FFF;
            byte memValue;

            switch (addr & 0xC000)
            {
            case 0x0000:
                return(SpecialMode
                        ? RamBanks[_slots[0]][memIndex]
                        : CurrentRomPage[memIndex]);

            case 0x4000:
                memValue = RamBanks[_slots[1]][memIndex];
                if (noContention || _screenDevice == null)
                {
                    return(memValue);
                }
                _cpu?.Delay(_screenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                return(memValue);

            case 0x8000:
                return(RamBanks[_slots[2]][memIndex]);

            default:
                var bankIndex = _slots[3];
                memValue = RamBanks[bankIndex][memIndex];
                if (bankIndex < 4)
                {
                    return(memValue);
                }

                // --- Bank 4, 5, 6, and 7 are contended
                _cpu?.Delay(_screenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                return(memValue);
            }
        }
Exemple #8
0
 /// <summary>
 /// Emulates I/O contention
 /// </summary>
 /// <param name="addr">Contention address</param>
 public void ContentionWait(ushort addr)
 {
     Cpu.Delay(4);
 }
Exemple #9
0
        /// <summary>
        /// Emulates I/O contention
        /// </summary>
        /// <param name="addr">Contention address</param>
        public virtual void ContentionWait(ushort addr)
        {
            var lowBit = (addr & 0x0001) != 0;

            if ((addr & 0xc000) == 0x4000 ||
                (addr & 0xc000) == 0xC000 && IsContendedBankPagedIn())
            {
                if (lowBit)
                {
                    // --- C:1 x 4 contention scheme
                    Cpu.Delay(ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                    Cpu.Delay(1);
                    Cpu.Delay(ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                    Cpu.Delay(1);
                    Cpu.Delay(ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                    Cpu.Delay(1);
                    Cpu.Delay(ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                    Cpu.Delay(1);
                }
                else
                {
                    // --- C:1, C:3 contention scheme
                    Cpu.Delay(ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                    Cpu.Delay(1);
                    Cpu.Delay(ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                    Cpu.Delay(3);
                }
            }
            else
            {
                if (lowBit)
                {
                    // --- N:4 contention scheme
                    Cpu.Delay(4);
                }
                else
                {
                    // --- N:1, C:3 contention scheme
                    Cpu.Delay(1);
                    Cpu.Delay(ScreenDevice.GetContentionValue(HostVm.CurrentFrameTact));
                    Cpu.Delay(3);
                }
            }
        }