示例#1
0
        public void ProcessMicBitAbortsInPassiveMode()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = 0x0038;
            td.SetTapeMode();

            // --- Act
            td.ProcessMicBit(true);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Passive);
            td.SavePhase.ShouldBe(SavePhase.None);
        }
示例#2
0
        public void ProcessMicBitWorksInSaveModeWithBitChange()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.SaveBytesRoutineAddress;
            td.SetTapeMode();

            // --- Act
            td.ProcessMicBit(false);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.None);
        }
示例#3
0
        public void GetEarBitsReturnTrueInLoadModeWithNoPlayer()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.LoadBytesRoutineAddress;
            td.SetTapeMode();

            // --- Act
            var bit = td.GetEarBit(0);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Load);
            bit.ShouldBeTrue();
        }
示例#4
0
        public void GetEarBitsReturnTrueInPassiveMode()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = 0x0038;
            td.SetTapeMode();

            // --- Act
            var bit = td.GetEarBit(0);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Passive);
            bit.ShouldBeTrue();
        }
示例#5
0
        public void CreateTapeFileIsInvokedWhenEnteringSaveMode()
        {
            // --- Arrange
            var vm       = new SpectrumTapeDeviceTestMachine();
            var provider = new FakeTapeProvider();
            var td       = new TapeDevice(provider, provider);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.SaveBytesRoutineAddress;

            // --- Act
            td.SetTapeMode();

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            provider.CreateTapeFileInvoked.ShouldBeTrue();
        }
示例#6
0
        public void ProcessMicBitAbortsInLoadMode()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = vm.RomInfo.LoadBytesRoutineAddress;
            td.SetTapeMode();

            // --- Act
            td.ProcessMicBit(true);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Load);
            td.SavePhase.ShouldBe(SavePhase.None);
        }
示例#7
0
        public void SetTapeModeLeavesLoadModeWhenEof()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(new EmptyTapeContentProvider());

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.LoadBytesRoutineAddress;
            td.SetTapeMode();
            var before = td.CurrentMode;

            // --- Act
            td.SetTapeMode();

            // --- Assert
            before.ShouldBe(TapeOperationMode.Load);
            td.CurrentMode.ShouldBe(TapeOperationMode.Passive);
        }
示例#8
0
        public void SetTapeModeInvokesEnteredLoadModeEvent()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.LoadBytesRoutineAddress;
            var invoked = false;

            td.EnteredLoadMode += (sender, args) => { invoked = true; };

            // --- Act
            td.SetTapeMode();

            // --- Assert
            invoked.ShouldBeTrue();
        }
示例#9
0
        public void SaveTzxBlockIsCalledWhenCompletingDataBlock()
        {
            // --- Arrange
            var vm       = new SpectrumTapeDeviceTestMachine();
            var provider = new FakeTapeProvider();
            var td       = new TapeDevice(provider, provider);

            td.OnAttachedToVm(vm);
            var testData = new byte[] { 0x90, 0x02, 0x05, 0xAA, 0xFF, 0x63 };

            // --- Act
            EmitFullDataBlock(vm, td, testData);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.None);
            provider.SaveTzxBlockInvoked.ShouldBeTrue();
        }
示例#10
0
        public void ProcessMicBitFailsWithLongBit1Pulse()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            (var debugCpu, var tacts, var pulse) = EmitHeaderWithSync(vm, td);

            // --- Act
            tacts += TapeDataBlockPlayer.BIT_1_PL + TapeDevice.SAVE_PULSE_TOLERANCE + 1;
            debugCpu.SetTacts(tacts);
            td.ProcessMicBit(pulse);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.Error);
        }
示例#11
0
        public void ProcessMicBitFailsWithLongPilotPulse()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.SaveBytesRoutineAddress;
            td.SetTapeMode();
            var debugCpu = vm.Cpu as IZ80CpuTestSupport;

            // --- Act
            debugCpu.SetTacts(TapeDataBlockPlayer.PILOT_PL + TapeDevice.SAVE_PULSE_TOLERANCE + 1);
            td.ProcessMicBit(false);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.Error);
        }
示例#12
0
        public void SetTapeModeLeavesSaveModeWhenError()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.SaveBytesRoutineAddress;
            td.SetTapeMode();
            var before = td.CurrentMode;

            // --- Act
            vm.Cpu.Registers.PC = TapeDevice.ERROR_ROM_ADDRESS;
            td.SetTapeMode();

            // --- Assert
            before.ShouldBe(TapeOperationMode.Save);
            td.CurrentMode.ShouldBe(TapeOperationMode.Passive);
        }
示例#13
0
        public void ProcessMicBitCatchesFirstPilotPulse()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.SaveBytesRoutineAddress;
            td.SetTapeMode();
            var debugCpu = vm.Cpu as IZ80CpuTestSupport;

            // --- Act
            debugCpu.SetTacts(TapeDataBlockPlayer.PILOT_PL);
            td.ProcessMicBit(false);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.Pilot);
            td.PilotPulseCount.ShouldBe(1);
        }
示例#14
0
        public void ProcessMicBitFailsWithShortTermSyncPulse()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            var testData = new byte[] { 0x90, 0x02, 0x05, 0xAA, 0xFF, 0x63 };

            (var debugCpu, var tacts, var pulse) = EmitHeaderAndData(vm, td, testData);

            // --- Act
            tacts += TapeDataBlockPlayer.TERM_SYNC - TapeDevice.SAVE_PULSE_TOLERANCE - 1;
            debugCpu.SetTacts(tacts);
            td.ProcessMicBit(pulse);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.Error);
        }
示例#15
0
        public void SetTapeModeInvokesLeftSaveModeWhenError()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.SaveBytesRoutineAddress;
            td.SetTapeMode();
            var invoked = false;

            td.LeftSaveMode += (sender, args) => { invoked = true; };

            // --- Act
            vm.Cpu.Registers.PC = TapeDevice.ERROR_ROM_ADDRESS;
            td.SetTapeMode();

            // --- Assert
            invoked.ShouldBeTrue();
        }
示例#16
0
        public void SetTapeModeLeavesSaveModeAfterSilence()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.SaveBytesRoutineAddress;
            td.SetTapeMode();
            var before = td.CurrentMode;

            // --- Act
            var debugCpu = vm.Cpu as IZ80CpuTestSupport;

            debugCpu.SetTacts(2 * TapeDevice.SAVE_STOP_SILENCE);
            td.SetTapeMode();

            // --- Assert
            before.ShouldBe(TapeOperationMode.Save);
            td.CurrentMode.ShouldBe(TapeOperationMode.Passive);
        }
示例#17
0
        public void SetNameIsNotCalledWithInvalidHeader()
        {
            // --- Arrange
            var vm       = new SpectrumTapeDeviceTestMachine();
            var provider = new FakeTapeProvider();
            var td       = new TapeDevice(provider, provider);

            td.OnAttachedToVm(vm);
            var testData = new byte[]
            {
                0x42, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20
            };

            // --- Act
            EmitFullDataBlock(vm, td, testData);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.None);
            provider.SuggestedName.ShouldBeNull();
        }
示例#18
0
        public void ProcessMicBitWorksWithBit1Pulse()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            (var debugCpu, var tacts, var pulse) = EmitHeaderWithSync(vm, td);

            // --- Act
            tacts += TapeDataBlockPlayer.BIT_1_PL;
            debugCpu.SetTacts(tacts);
            td.ProcessMicBit(pulse);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.Data);
            td.BitOffset.ShouldBe(0);
            td.DataByte.ShouldBe((byte)0);
            td.PrevDataPulse.ShouldBe(MicPulseType.Bit1);
        }
示例#19
0
        public void ProcessMicBitWorksWithDataBytes()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            var testData = new byte[] { 0x90, 0x02, 0x05, 0xAA, 0xFF, 0x63 };

            // --- Act
            EmitHeaderAndData(vm, td, testData);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.Data);
            td.DataLength.ShouldBe(testData.Length);
            for (var i = 0; i < testData.Length; i++)
            {
                td.DataBuffer[i].ShouldBe(testData[i]);
            }
        }
示例#20
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);

            // Check whether the low bit is reset
            // Technically the ULA should respond to every even I/O address
            if ((port & 0x0001) != 0)
            {
                return;
            }

            // 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))
            {
                // border value has changed - update the screen buffer
                ULADevice.UpdateScreenBuffer(CurrentFrameCycle);
            }

            ULADevice.borderColour = value & BORDER_BIT;

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

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

            // Tape mic processing (not implemented yet)
            //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
        }
示例#21
0
        public void SetTapeModeInvokesLedtSaveModeEventAfterSilence()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.SaveBytesRoutineAddress;
            td.SetTapeMode();
            var invoked = false;

            td.LeftSaveMode += (sender, args) => { invoked = true; };

            // --- Act
            var debugCpu = vm.Cpu as IZ80CpuTestSupport;

            debugCpu.SetTacts(2 * TapeDevice.SAVE_STOP_SILENCE);
            td.SetTapeMode();

            // --- Assert
            invoked.ShouldBeTrue();
        }
示例#22
0
        public void SetNameIsCalledAtFirstDataBlock()
        {
            // --- Arrange
            var vm           = new SpectrumTapeDeviceTestMachine();
            var saveProvider = new FakeSaveToTapeProvider();
            var td           = new TapeDevice(saveProvider);

            td.OnAttachedToVm(vm);
            var testData = new byte[]
            {
                0x00, 0x00,
                0x42, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20,
                0x4F, 0x00, 0x6F, 0x80, 0x4F, 0x00, 0xC3
            };

            // --- Act
            EmitFullDataBlock(vm, td, testData);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.None);
            saveProvider.SuggestedName.ShouldBe("Border");
        }
示例#23
0
        public void FinalizeTapeFileIsInvokedWhenLeavingSaveMode()
        {
            // --- Arrange
            var vm           = new SpectrumTapeDeviceTestMachine();
            var saveProvider = new FakeSaveToTapeProvider();
            var td           = new TapeDevice(saveProvider);

            td.OnAttachedToVm(vm);
            vm.Cpu.Registers.PC = td.SaveBytesRoutineAddress;
            td.SetTapeMode();
            var before = td.CurrentMode;

            // --- Act
            var debugCpu = vm.Cpu as IZ80CpuTestSupport;

            debugCpu.SetTacts(2 * TapeDevice.SAVE_STOP_SILENCE);
            td.SetTapeMode();

            // --- Assert
            before.ShouldBe(TapeOperationMode.Save);
            td.CurrentMode.ShouldBe(TapeOperationMode.Passive);
            saveProvider.FinalizeTapeFileInvoked.ShouldBeTrue();
        }
        /// <summary>
        /// Writes a byte of data to a specified port address
        /// </summary>
        public override void WritePort(ushort port, byte value)
        {
            // Check whether the low bit is reset
            // Technically the ULA should respond to every even I/O address
            if ((port & 0x0001) != 0)
            {
                return;
            }

            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);

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

            // Tape mic processing (not implemented yet)
            //TapeDevice.ProcessMicBit((value & MIC_BIT) != 0);
        }
示例#25
0
        public void ProcessMicBitWorksWithTermSyncPulse()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            var testData = new byte[] { 0x90, 0x02, 0x05, 0xAA, 0xFF, 0x63 };

            (var debugCpu, var tacts, var pulse) = EmitHeaderAndData(vm, td, testData);

            // --- Act
            tacts += TapeDataBlockPlayer.TERM_SYNC;
            debugCpu.SetTacts(tacts);
            td.ProcessMicBit(pulse);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.None);
            for (var i = 0; i < testData.Length; i++)
            {
                td.DataBuffer[i].ShouldBe(testData[i]);
            }
        }
示例#26
0
        public void ProcessMicBitWorksWithMultipleDataBlock()
        {
            // --- Arrange
            var vm = new SpectrumTapeDeviceTestMachine();
            var td = new TapeDevice(null, null);

            td.OnAttachedToVm(vm);
            var testData = new byte[] { 0x90, 0x02, 0x05, 0xAA, 0xFF, 0x63 };

            // --- Act
            (var debugCpu, var tacts, var pulse) = EmitFullDataBlock(vm, td, testData);
            tacts += TapeDataBlockPlayer.PILOT_PL * 5;
            debugCpu.SetTacts(tacts);
            td.ProcessMicBit(pulse);
            (debugCpu, tacts, pulse) = EmitFullDataBlock(vm, td, testData);
            tacts += TapeDataBlockPlayer.PILOT_PL * 5;
            debugCpu.SetTacts(tacts);
            td.ProcessMicBit(pulse);

            // --- Assert
            td.CurrentMode.ShouldBe(TapeOperationMode.Save);
            td.SavePhase.ShouldBe(SavePhase.None);
            td.DataBlockCount.ShouldBe(2);
        }
示例#27
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;
        }
示例#28
0
        /// <summary>
        /// Reads a byte of data from a specified port address
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public override byte ReadPort(ushort port)
        {
            bool deviceAddressed = true;

            // process IO contention
            ContendPortAddress(port);

            int result = 0xFF;

            // check AY
            if (AYDevice.ReadPort(port, ref result))
            {
                return((byte)result);
            }

            // Kempston joystick input takes priority over all other input
            // if this is detected just return the kempston byte
            if ((port & 0xe0) == 0 || (port & 0x20) == 0)
            {
                if (LocateUniqueJoystick(JoystickType.Kempston) != null)
                {
                    return((byte)((KempstonJoystick)LocateUniqueJoystick(JoystickType.Kempston) as KempstonJoystick).JoyLine);
                }

                InputRead = true;
            }
            else if (UPDDiskDevice.ReadPort(port, ref result))
            {
                return((byte)result);
            }
            else
            {
                if (KeyboardDevice.ReadPort(port, ref result))
                {
                    // not a lagframe
                    InputRead = true;

                    // process tape INs
                    TapeDevice.ReadPort(port, ref result);
                }
                else
                {
                    deviceAddressed = false;
                }
            }

            if (!deviceAddressed)
            {
                // If this is an unused port the floating memory bus should be returned
                // Floating bus is read on the previous cycle
                long _tStates = CurrentFrameCycle - 1;

                // if we are on the top or bottom border return 0xff
                if ((_tStates < ULADevice.contentionStartPeriod) || (_tStates > ULADevice.contentionEndPeriod))
                {
                    result = 0xff;
                }
                else
                {
                    if (ULADevice.floatingBusTable[_tStates] < 0)
                    {
                        result = 0xff;
                    }
                    else
                    {
                        result = ReadBus((ushort)ULADevice.floatingBusTable[_tStates]);
                    }
                }
            }

            return((byte)result);
        }
示例#29
0
        public void SyncState(Serializer ser)
        {
            ser.BeginSection("ZXMachine");
            ser.Sync("FrameCompleted", ref FrameCompleted);
            ser.Sync("OverFlow", ref OverFlow);
            ser.Sync("FrameCount", ref FrameCount);
            ser.Sync("_frameCycles", ref _frameCycles);
            ser.Sync("inputRead", ref inputRead);
            ser.Sync("LastFrameStartCPUTick", ref LastFrameStartCPUTick);
            ser.Sync("LastULAOutByte", ref LastULAOutByte);
            ser.Sync("ROM0", ref ROM0, false);
            ser.Sync("ROM1", ref ROM1, false);
            ser.Sync("ROM2", ref ROM2, false);
            ser.Sync("ROM3", ref ROM3, false);
            ser.Sync("RAM0", ref RAM0, false);
            ser.Sync("RAM1", ref RAM1, false);
            ser.Sync("RAM2", ref RAM2, false);
            ser.Sync("RAM3", ref RAM3, false);
            ser.Sync("RAM4", ref RAM4, false);
            ser.Sync("RAM5", ref RAM5, false);
            ser.Sync("RAM6", ref RAM6, false);
            ser.Sync("RAM7", ref RAM7, false);
            ser.Sync("ROMPaged", ref ROMPaged);
            ser.Sync("SHADOWPaged", ref SHADOWPaged);
            ser.Sync("RAMPaged", ref RAMPaged);
            ser.Sync("PagingDisabled", ref PagingDisabled);
            ser.Sync("SpecialPagingMode", ref SpecialPagingMode);
            ser.Sync("PagingConfiguration", ref PagingConfiguration);
            ser.Sync("ROMhigh", ref ROMhigh);
            ser.Sync("ROMlow", ref ROMlow);
            ser.Sync("LastContendedReadByte", ref LastContendedReadByte);

            KeyboardDevice.SyncState(ser);
            BuzzerDevice.SyncState(ser);
            TapeBuzzer.SyncState(ser);
            ULADevice.SyncState(ser);
            CPUMon.SyncState(ser);

            if (AYDevice != null)
            {
                AYDevice.SyncState(ser);
                ((AY38912)AYDevice as AY38912).PanningConfiguration = Spectrum.Settings.AYPanConfig;
            }

            ser.Sync("tapeMediaIndex", ref tapeMediaIndex);
            if (ser.IsReader)
            {
                IsLoadState    = true;
                TapeMediaIndex = tapeMediaIndex;
                IsLoadState    = false;
            }


            TapeDevice.SyncState(ser);

            ser.Sync("diskMediaIndex", ref diskMediaIndex);
            if (ser.IsReader)
            {
                IsLoadState    = true;
                DiskMediaIndex = diskMediaIndex;
                IsLoadState    = false;
            }

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

            ser.EndSection();
        }
示例#30
0
        /// <summary>
        /// Executes a single frame
        /// </summary>
        public virtual void ExecuteFrame(bool render, bool renderSound)
        {
            ULADevice.FrameEnd        = false;
            ULADevice.ULACycleCounter = CurrentFrameCycle;

            InputRead    = false;
            _render      = render;
            _renderSound = renderSound;

            FrameCompleted = false;

            if (UPDDiskDevice == null || !UPDDiskDevice.FDD_IsDiskLoaded)
            {
                TapeDevice.StartFrame();
            }

            if (_renderSound)
            {
                if (AYDevice != null)
                {
                    AYDevice.StartFrame();
                }
            }

            PollInput();

            for (;;)
            {
                // run the CPU Monitor cycle
                CPUMon.ExecuteCycle();

                // cycle the tape device
                if (UPDDiskDevice == null || !UPDDiskDevice.FDD_IsDiskLoaded)
                {
                    TapeDevice.TapeCycle();
                }

                // has frame end been reached?
                if (ULADevice.FrameEnd)
                {
                    break;
                }
            }

            OverFlow = (int)CurrentFrameCycle - ULADevice.FrameLength;

            // we have reached the end of a frame
            LastFrameStartCPUTick = CPU.TotalExecutedCycles - OverFlow;

            ULADevice.LastTState = 0;

            if (AYDevice != null)
            {
                AYDevice.EndFrame();
            }

            FrameCount++;

            if (UPDDiskDevice == null || !UPDDiskDevice.FDD_IsDiskLoaded)
            {
                TapeDevice.EndFrame();
            }

            FrameCompleted = true;

            // is this a lag frame?
            Spectrum.IsLagFrame = !InputRead;

            // FDC debug
            if (UPDDiskDevice != null && UPDDiskDevice.writeDebug)
            {
                // only write UPD log every second
                if (FrameCount % 10 == 0)
                {
                    System.IO.File.AppendAllLines(UPDDiskDevice.outputfile, UPDDiskDevice.dLog);
                    UPDDiskDevice.dLog = new System.Collections.Generic.List <string>();
                    //System.IO.File.WriteAllText(UPDDiskDevice.outputfile, UPDDiskDevice.outputString);
                }
            }
        }