예제 #1
0
        /// <summary>
        /// Writes a byte of data to a specified port address
        /// </summary>
        /// <param name="port"></param>
        /// <param name="value"></param>
        public override void WritePort(ushort port, byte value)
        {
            // process IO contention
            ContendPortAddress(port);

            // get a BitArray of the port
            BitArray portBits = new BitArray(BitConverter.GetBytes(port));
            // get a BitArray of the value byte
            BitArray bits = new BitArray(new byte[] { value });

            // Check whether the low bit is reset
            bool lowBitReset = !portBits[0]; // (port & 0x01) == 0;

            AYDevice.WritePort(port, value);

            UPDDiskDevice.WritePort(port, value);

            // port 0x7ffd - hardware should only respond when bits 1 & 15 are reset and bit 14 is set
            if (port == 0x7ffd)
            {
                if (!PagingDisabled)
                {
                    // bits 0, 1, 2 select the RAM page
                    var rp = value & 0x07;
                    if (rp < 8)
                    {
                        RAMPaged = rp;
                    }

                    // bit 3 controls shadow screen
                    SHADOWPaged = bits[3];

                    // Bit 5 set signifies that paging is disabled until next reboot
                    PagingDisabled = bits[5];

                    // portbit 4 is the LOW BIT of the ROM selection
                    ROMlow = bits[4];
                }
            }
            // port 0x1ffd - hardware should only respond when bits 1, 13, 14 & 15 are reset and bit 12 is set
            if (port == 0x1ffd)
            {
                if (!PagingDisabled)
                {
                    if (!bits[0])
                    {
                        // special paging is not enabled - get the ROMpage high byte
                        ROMhigh = bits[2];

                        // set the special paging mode flag
                        SpecialPagingMode = false;
                    }
                    else
                    {
                        // special paging is enabled
                        // this is decided based on combinations of bits 1 & 2
                        // Config 0 = Bit1-0 Bit2-0
                        // Config 1 = Bit1-1 Bit2-0
                        // Config 2 = Bit1-0 Bit2-1
                        // Config 3 = Bit1-1 Bit2-1
                        BitArray confHalfNibble = new BitArray(2);
                        confHalfNibble[0] = bits[1];
                        confHalfNibble[1] = bits[2];

                        // set special paging configuration
                        PagingConfiguration = ZXSpectrum.GetIntFromBitArray(confHalfNibble);

                        // set the special paging mode flag
                        SpecialPagingMode = true;
                    }
                }

                // bit 4 is the printer port strobe
                PrinterPortStrobe = bits[4];
            }

            // Only even addresses address the ULA
            if (lowBitReset)
            {
                // store the last OUT byte
                LastULAOutByte = value;

                /*
                 *  Bit   7   6   5   4   3   2   1   0
                 +-------------------------------+
                 |   |   |   | E | M |   Border  |
                 +-------------------------------+
                 */

                // Border - LSB 3 bits hold the border colour
                if (ULADevice.borderColour != (value & BORDER_BIT))
                {
                    ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
                }

                ULADevice.borderColour = value & BORDER_BIT;

                // Buzzer
                BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0);

                // Tape
                TapeDevice.WritePort(port, value);

                // Tape
                //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
            }


            LastULAOutByte = value;
        }
예제 #2
0
        /// <summary>
        /// Writes a byte of data to a specified port address
        /// </summary>
        public override void WritePort(ushort port, byte value)
        {
            // get a BitArray of the port
            BitArray portBits = new BitArray(BitConverter.GetBytes(port));
            // get a BitArray of the value byte
            BitArray bits = new BitArray(new byte[] { value });

            // handle AY port writes
            AYDevice.WritePort(port, value);

            // memory paging
            // this is controlled by writes to port 0x7ffd
            // but it is only partially decoded so it actually responds to any port with bits 1 and 15 reset
            if (portBits[1] == false && portBits[15] == false)
            {
                Last7ffd = value;

                // if paging is disabled then all writes to this port are ignored until the next reboot
                if (!PagingDisabled)
                {
                    // Bits 0, 1, 2 select the RAM page
                    var rp = value & 0x07;
                    if (RAMPaged != rp && rp < 8)
                    {
                        RAMPaged = rp;
                    }

                    // bit 3 controls shadow screen
                    if (SHADOWPaged != bits[3])
                    {
                        SHADOWPaged = bits[3];
                    }

                    // ROM page
                    if (bits[4])
                    {
                        // 48k basic rom
                        ROMPaged = 1;
                    }
                    else
                    {
                        // 128k editor and menu system
                        ROMPaged = 0;
                    }

                    // Bit 5 set signifies that paging is disabled until next reboot
                    PagingDisabled = bits[5];
                }
                else
                {
                    // no changes to paging
                }
            }

            if (port == 0x1ffd)
            {
            }

            // Check whether the low bit is reset
            // Technically the ULA should respond to every even I/O address
            bool lowBitReset = !portBits[0]; // (port & 0x01) == 0;

            // Only even addresses address the ULA
            if (lowBitReset)
            {
                LastFe = value;

                // store the last OUT byte
                LastULAOutByte = value;

                /*
                 *  Bit   7   6   5   4   3   2   1   0
                 +-------------------------------+
                 |   |   |   | E | M |   Border  |
                 +-------------------------------+
                 */

                // Border - LSB 3 bits hold the border colour
                if (ULADevice.BorderColor != (value & BORDER_BIT))
                {
                    //ULADevice.RenderScreen((int)CurrentFrameCycle);
                    ULADevice.BorderColor = value & BORDER_BIT;
                }

                // Buzzer
                BuzzerDevice.ProcessPulseValue((value & EAR_BIT) != 0, _renderSound);
                TapeDevice.WritePort(port, value);

                // Tape
                //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
            }
        }