public ZXSpectrumComputer()
        {
            // -- Initialize components --

            // System clock
            Clock = new _Clock(Clock.FREQ_3_5MHZ);
            // Init CPU
            CPU = new _Z80CPU();
            // Reset button
            ResetButton = new Button(SignalState.HIGH);

            // ZX Spectrum memory map
            /// NB : in the real machine, there is also a multiplexed address bus for each device :
            /// select row (7 bits) then select colum (7bits).
            /// Row and column address strobe - RAS/CAS - signals must therefore be generated.
            /// We do not simulate theses details here, as they are complex to understand
            /// and can be ignored without losing any fildelity to the behavior of the machine.

            // 16K ROM
            // 0 - 16383 : ROM Program
            ROM = new _ROM();
            // 16K RAM
            // 16384 - 23295 : Video display memory (6910 bytes)
            // 23296 -  : System variables
            // User programs
            RAM16K = new _DualAccessMemoryMappedChip(Memory.BYTES_16K, 0x4000);
            // 32K RAM (only in 48K models)
            RAM32K = new _MemoryMappedChip(Memory.BYTES_32K, 0x8000);

            // Initialize ULA :
            //   Video generator
            //   CPU clock generator
            //   Memory access governor
            //   Keyboard controller
            //   Tape I/O controller
            //   Speaker controller
            ULA = new _ULA();

            // Initialize peripherals
            Keyboard     = new _Keyboard();
            Screen       = new _Screen();
            Speaker      = new _Speaker();
            TapeRecorder = new _TapeRecorder();

            // Initialize Sinclair joysticks
            Joystick1 = new Joystick(true, Keyboard);
            Joystick2 = new Joystick(false, Keyboard);

            // -- Initialize and connect system buses --

            // CPU buses
            AddressBus = new Bus <ushort>();
            DataBus    = new Bus <byte>();
            CPU.Address.ConnectTo(AddressBus);
            CPU.Data.ConnectTo(DataBus);
            ROM.Address.ConnectTo(AddressBus);
            ROM.Data.ConnectTo(DataBus);
            RAM16K.AddressInput1.ConnectTo(AddressBus);
            RAM16K.DataInput1.ConnectTo(DataBus);
            RAM32K.Address.ConnectTo(AddressBus);
            RAM32K.Data.ConnectTo(DataBus);
            ULA.Address.ConnectTo(AddressBus);
            ULA.Data.ConnectTo(DataBus);

            // Dedicated video buses : firect Video Memory Access for the ULA
            VideoAddressBus = new Bus <ushort>();
            VideoDataBus    = new Bus <byte>();
            ULA.VideoAddress.ConnectTo(VideoAddressBus);
            ULA.VideoData.ConnectTo(VideoDataBus);
            RAM16K.AddressInput2.ConnectTo(VideoAddressBus);
            RAM16K.DataInput2.ConnectTo(VideoDataBus);

            // Connect Keyboard to the ULA
            KeyboardDataBus = new Bus <byte>();
            ULA.KeyboardData.ConnectTo(KeyboardDataBus);
            Keyboard.Address.ConnectTo(AddressBus);
            Keyboard.Data.ConnectTo(KeyboardDataBus);

            // Connect ULA analog video signal to screen
            ULA.ColorSignal.ConnectTo(Screen.ColorSignal);

            // Connect tape recorder sound output to ULA
            TapeRecorder.SoundSignal.ConnectTo(ULA.TapeInputSignal);

            // Connect ULA sound output to the speaker
            ULA.SpeakerSoundSignal.ConnectTo(Speaker.SoundSignal);

            // -- Connect individual PINs --

            ((_Clock)Clock).ConnectTo(ULA, Screen, TapeRecorder);
            ((_Z80CPU)CPU).ConnectTo(ResetButton, ULA, ROM, RAM16K, RAM32K);
            ((_ROM)ROM).ConnectTo(CPU);
            ((_DualAccessMemoryMappedChip)RAM16K).ConnectTo(CPU, ULA);
            ((_MemoryMappedChip)RAM32K).ConnectTo(CPU);
            ((_ULA)ULA).ConnectTo(Clock, CPU, RAM16K, Keyboard, Screen, Speaker);
            ((_Keyboard)Keyboard).ConnectTo(ULA);
            ((_Screen)Screen).ConnectTo(ULA);
            ((_Speaker)Speaker).ConnectTo(ULA);
            ((_TapeRecorder)TapeRecorder).ConnectTo(Clock);
        }
        public ZXSpectrumComputer()
        {
            // -- Initialize components --

            // System clock
            Clock = new _Clock(Clock.FREQ_3_5MHZ);
            // Init CPU
            CPU = new _Z80CPU();
            // Reset button
            ResetButton = new Button(SignalState.HIGH);

            // ZX Spectrum memory map
            /// NB : in the real machine, there is also a multiplexed address bus for each device :
            /// select row (7 bits) then select colum (7bits).
            /// Row and column address strobe - RAS/CAS - signals must therefore be generated.
            /// We do not simulate theses details here, as they are complex to understand
            /// and can be ignored without losing any fildelity to the behavior of the machine.

            // 16K ROM
            // 0 - 16383 : ROM Program
            ROM = new _ROM();
            // 16K RAM
            // 16384 - 23295 : Video display memory (6910 bytes)
            // 23296 -  : System variables
            // User programs
            RAM16K = new _DualAccessMemoryMappedChip(Memory.BYTES_16K, 0x4000);
            // 32K RAM (only in 48K models)
            RAM32K = new _MemoryMappedChip(Memory.BYTES_32K, 0x8000);

            // Initialize ULA :
            //   Video generator
            //   CPU clock generator
            //   Memory access governor
            //   Keyboard controller
            //   Tape I/O controller
            //   Speaker controller
            ULA = new _ULA();

            // Initialize peripherals
            Keyboard = new _Keyboard();
            Screen = new _Screen();
            Speaker = new _Speaker();
            TapeRecorder = new _TapeRecorder();

            // Initialize Sinclair joysticks
            Joystick1 = new Joystick(true, Keyboard);
            Joystick2 = new Joystick(false, Keyboard);

            // -- Initialize and connect system buses --

            // CPU buses
            AddressBus = new Bus<ushort>();
            DataBus = new Bus<byte>();
            CPU.Address.ConnectTo(AddressBus);
            CPU.Data.ConnectTo(DataBus);
            ROM.Address.ConnectTo(AddressBus);
            ROM.Data.ConnectTo(DataBus);
            RAM16K.AddressInput1.ConnectTo(AddressBus);
            RAM16K.DataInput1.ConnectTo(DataBus);
            RAM32K.Address.ConnectTo(AddressBus);
            RAM32K.Data.ConnectTo(DataBus);
            ULA.Address.ConnectTo(AddressBus);
            ULA.Data.ConnectTo(DataBus);

            // Dedicated video buses : firect Video Memory Access for the ULA
            VideoAddressBus = new Bus<ushort>();
            VideoDataBus = new Bus<byte>();
            ULA.VideoAddress.ConnectTo(VideoAddressBus);
            ULA.VideoData.ConnectTo(VideoDataBus);
            RAM16K.AddressInput2.ConnectTo(VideoAddressBus);
            RAM16K.DataInput2.ConnectTo(VideoDataBus);

            // Connect Keyboard to the ULA
            KeyboardDataBus = new Bus<byte>();
            ULA.KeyboardData.ConnectTo(KeyboardDataBus);
            Keyboard.Address.ConnectTo(AddressBus);
            Keyboard.Data.ConnectTo(KeyboardDataBus);

             // Connect ULA analog video signal to screen
            ULA.ColorSignal.ConnectTo(Screen.ColorSignal);

            // Connect tape recorder sound output to ULA
            TapeRecorder.SoundSignal.ConnectTo(ULA.TapeInputSignal);

            // Connect ULA sound output to the speaker
            ULA.SpeakerSoundSignal.ConnectTo(Speaker.SoundSignal);

            // -- Connect individual PINs --

            ((_Clock)Clock).ConnectTo(ULA, Screen, TapeRecorder);
            ((_Z80CPU)CPU).ConnectTo(ResetButton, ULA, ROM, RAM16K, RAM32K);
            ((_ROM)ROM).ConnectTo(CPU);
            ((_DualAccessMemoryMappedChip)RAM16K).ConnectTo(CPU, ULA);
            ((_MemoryMappedChip)RAM32K).ConnectTo(CPU);
            ((_ULA)ULA).ConnectTo(Clock, CPU, RAM16K, Keyboard, Screen, Speaker);
            ((_Keyboard)Keyboard).ConnectTo(ULA);
            ((_Screen)Screen).ConnectTo(ULA);
            ((_Speaker)Speaker).ConnectTo(ULA);
            ((_TapeRecorder)TapeRecorder).ConnectTo(Clock);
        }