diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.ISettable.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.ISettable.cs index ca5206d5d7..ab495acba4 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.ISettable.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.ISettable.cs @@ -91,11 +91,16 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC [DefaultValue(true)] public bool DeterministicEmulation { get; set; } - [DisplayName("CPC model")] + [DisplayName("CPC Model")] [Description("The model of Amstrad CPC machine to be emulated")] [DefaultValue(MachineType.CPC464)] public MachineType MachineType { get; set; } + [DisplayName("Auto Start/Stop Tape")] + [Description("If true, CPCHawk will automatically start and stop the tape when the tape motor is triggered")] + [DefaultValue(true)] + public bool AutoStartStopTape { get; set; } + public AmstradCPCSyncSettings Clone() { return (AmstradCPCSyncSettings)MemberwiseClone(); diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.Messaging.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.Messaging.cs index 2be71970a6..b80977c5c2 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.Messaging.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.Messaging.cs @@ -167,6 +167,34 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Emulator); } + /// + /// Tape message that is fired when tape is playing + /// + public void OSD_TapeMotorActive() + { + if (_tapeInfo.Count == 0) + return; + + StringBuilder sb = new StringBuilder(); + sb.Append("MOTOR ON (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")"); + + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + } + + /// + /// Tape message that is fired when tape is playing + /// + public void OSD_TapeMotorInactive() + { + if (_tapeInfo.Count == 0) + return; + + StringBuilder sb = new StringBuilder(); + sb.Append("MOTOR OFF (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")"); + + SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); + } + /// /// Tape message that is fired when tape is playing /// @@ -176,7 +204,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC return; StringBuilder sb = new StringBuilder(); - sb.Append("PLAYING (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")"); + sb.Append("PLAYING MANUAL (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")"); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } @@ -190,7 +218,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC return; StringBuilder sb = new StringBuilder(); - sb.Append("STOPPED (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")"); + sb.Append("STOPPED MANUAL (" + _machine.TapeMediaIndex + ": " + _tapeInfo[_machine.TapeMediaIndex].Name + ")"); SendMessage(sb.ToString().TrimEnd('\n'), MessageCategory.Tape); } diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.cs index 18c0270eb6..49a56df3a6 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/AmstradCPC.cs @@ -46,7 +46,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC { case MachineType.CPC464: ControllerDefinition = AmstradCPCControllerDefinition; - Init(MachineType.CPC464, _files); + Init(MachineType.CPC464, _files, ((AmstradCPCSyncSettings)syncSettings as AmstradCPCSyncSettings).AutoStartStopTape); break; default: throw new InvalidOperationException("Machine not yet emulated"); @@ -139,7 +139,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC private MachineType _machineType; - private void Init(MachineType machineType, List files) + private void Init(MachineType machineType, List files, bool autoTape) { _machineType = machineType; @@ -147,7 +147,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC switch (machineType) { case MachineType.CPC464: - _machine = new CPC464(this, _cpu, files); + _machine = new CPC464(this, _cpu, files, autoTape); var _systemRom16 = GetFirmware(0x4000, "464ROM"); var romData16 = RomData.InitROM(machineType, _systemRom16); _machine.InitROM(romData16); diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs index 3fc4052397..7bc4c9c247 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Datacorder/DatacorderDevice.cs @@ -8,22 +8,22 @@ using System.Text; namespace BizHawk.Emulation.Cores.Computers.AmstradCPC { /// - /// Represents the tape device (or build-in datacorder as it was called +2 and above) + /// Represents the tape device /// - public class DatacorderDevice : IPortIODevice + public class DatacorderDevice { #region Construction - private CPCBase _machine { get; set; } - private Z80A _cpu { get; set; } - private IBeeperDevice _buzzer { get; set; } + private CPCBase _machine; + private Z80A _cpu => _machine.CPU; + private IBeeperDevice _buzzer => _machine.TapeBuzzer; /// /// Default constructor /// - public DatacorderDevice() + public DatacorderDevice(bool autoTape) { - + _autoPlay = autoTape; } /// @@ -33,8 +33,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC public void Init(CPCBase machine) { _machine = machine; - _cpu = _machine.CPU; - _buzzer = machine.TapeBuzzer; } #endregion @@ -44,7 +42,38 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// /// Signs whether the tape motor is running /// - public bool TapeMotor; + private bool tapeMotor; + public bool TapeMotor + { + get { return tapeMotor; } + set + { + if (tapeMotor == value) + return; + + tapeMotor = value; + if (tapeMotor) + { + _machine.CPC.OSD_TapeMotorActive(); + + if (_autoPlay) + { + Play(); + } + } + + else + { + _machine.CPC.OSD_TapeMotorInactive(); + + if (_autoPlay) + { + Stop(); + } + } + + } + } /// /// Internal counter used to trigger tape buzzer output @@ -140,7 +169,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// public void EndFrame() { - MonitorFrame(); + //MonitorFrame(); } public void StartFrame() @@ -160,8 +189,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC if (_tapeIsPlaying) return; + if (!_autoPlay) _machine.CPC.OSD_TapePlaying(); + _machine.CPC.OSD_TapeMotorActive(); + // update the lastCycle _lastCycle = _cpu.TotalExecutedCycles; @@ -368,7 +400,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// public void TapeCycle() { - if (TapeIsPlaying) + if (TapeMotor) { counter++; @@ -391,10 +423,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC // decide how many cycles worth of data we are capturing long cycles = cpuCycle - _lastCycle; - //bool is48k = _machine.IsIn48kMode(); - // check whether tape is actually playing - if (_tapeIsPlaying == false) + if (tapeMotor == false) { // it's not playing. Update lastCycle and return _lastCycle = cpuCycle; @@ -415,7 +445,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC // decrement cycles cycles -= _waitEdge; - if (_position == 0 && _tapeIsPlaying) + if (_position == 0 && tapeMotor) { // start of block - take care of initial pulse level for PZX switch (_dataBlocks[_currentDataBlockIndex].BlockDescription) @@ -437,6 +467,53 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC break; } + // most of these amstrad tapes appear to have a pause block at the start + // skip this if it is the first block + switch (_dataBlocks[_currentDataBlockIndex].BlockDescription) + { + case BlockType.PAUS: + case BlockType.PAUSE_BLOCK: + case BlockType.Pause_or_Stop_the_Tape: + if (_currentDataBlockIndex == 0) + { + // this is the first block on the tape + SkipBlock(true); + } + else + { + // there may be non-data blocks before this + bool okToSkipPause = true; + for (int i = _currentDataBlockIndex; i >= 0; i--) + { + switch (_dataBlocks[i].BlockDescription) + { + case BlockType.Archive_Info: + case BlockType.BRWS: + case BlockType.Custom_Info_Block: + case BlockType.Emulation_Info: + case BlockType.Glue_Block: + case BlockType.Hardware_Type: + case BlockType.Message_Block: + case BlockType.PZXT: + case BlockType.Text_Description: + break; + default: + okToSkipPause = false; + break; + } + + if (!okToSkipPause) + break; + } + + if (okToSkipPause) + { + SkipBlock(true); + } + } + break; + } + // notify about the current block var bl = _dataBlocks[_currentDataBlockIndex]; @@ -576,188 +653,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC currentState = !currentState; } - /// - /// Flash loading implementation - /// (Deterministic Emulation must be FALSE) - /// - private bool FlashLoad() - { - // deterministic emulation must = false - //if (_machine.Spectrum.SyncSettings.DeterministicEmulation) - //return; - - var util = _machine.CPC; - - if (_currentDataBlockIndex < 0) - _currentDataBlockIndex = 0; - - if (_currentDataBlockIndex >= DataBlocks.Count) - return false; - - //var val = GetEarBit(_cpu.TotalExecutedCycles); - //_buzzer.ProcessPulseValue(true, val); - - ushort addr = _cpu.RegPC; - - if (_machine.CPC.SyncSettings.DeterministicEmulation) - { - - } - - var tb = DataBlocks[_currentDataBlockIndex]; - var tData = tb.BlockData; - - if (tData == null || tData.Length < 2) - { - // skip this - return false; - } - - var toRead = tData.Length - 1; - - if (toRead < _cpu.Regs[_cpu.E] + (_cpu.Regs[_cpu.D] << 8)) - { - - } - else - { - toRead = _cpu.Regs[_cpu.E] + (_cpu.Regs[_cpu.D] << 8); - } - - if (toRead <= 0) - return false; - - var parity = tData[0]; - - if (parity != _cpu.Regs[_cpu.F_s] + (_cpu.Regs[_cpu.A_s] << 8) >> 8) - return false; - - util.SetCpuRegister("Shadow AF", 0x0145); - - for (var i = 0; i < toRead; i++) - { - var v = tData[i + 1]; - _cpu.Regs[_cpu.L] = v; - parity ^= v; - var d = (ushort)(_cpu.Regs[_cpu.Ixl] + (_cpu.Regs[_cpu.Ixh] << 8) + 1); - _machine.WriteBus(d, v); - } - var pc = (ushort)0x05DF; - - if (_cpu.Regs[_cpu.E] + (_cpu.Regs[_cpu.D] << 8) == toRead && - toRead + 1 < tData.Length) - { - var v = tData[toRead + 1]; - _cpu.Regs[_cpu.L] = v; - parity ^= v; - _cpu.Regs[_cpu.B] = 0xB0; - } - else - { - _cpu.Regs[_cpu.L] = 1; - _cpu.Regs[_cpu.B] = 0; - _cpu.Regs[_cpu.F] = 0x50; - _cpu.Regs[_cpu.A] = parity; - pc = 0x05EE; - } - - _cpu.Regs[_cpu.H] = parity; - var de = _cpu.Regs[_cpu.E] + (_cpu.Regs[_cpu.D] << 8); - util.SetCpuRegister("DE", de - toRead); - var ix = _cpu.Regs[_cpu.Ixl] + (_cpu.Regs[_cpu.Ixh] << 8); - util.SetCpuRegister("IX", ix + toRead); - - util.SetCpuRegister("PC", pc); - - _currentDataBlockIndex++; - - return true; - - } - #endregion #region TapeMonitor - private long _lastINCycle = 0; - private int _monitorCount; - private int _monitorTimeOut; - private ushort _monitorLastPC; - private ushort[] _monitorLastRegs = new ushort[7]; - - /// - /// Resets the TapeMonitor - /// - private void MonitorReset() - { - _lastINCycle = 0; - _monitorCount = 0; - _monitorLastPC = 0; - _monitorLastRegs = null; - } - - /// - /// An iteration of the monitor process - /// - public void MonitorRead() - { - long cpuCycle = _cpu.TotalExecutedCycles; - int delta = (int)(cpuCycle - _lastINCycle); - _lastINCycle = cpuCycle; - - var nRegs = new ushort[] - { - _cpu.Regs[_cpu.A], - _cpu.Regs[_cpu.B], - _cpu.Regs[_cpu.C], - _cpu.Regs[_cpu.D], - _cpu.Regs[_cpu.E], - _cpu.Regs[_cpu.H], - _cpu.Regs[_cpu.L] - }; - - if (delta > 0 && - delta < 96 && - _cpu.RegPC == _monitorLastPC && - _monitorLastRegs != null) - { - int dCnt = 0; - int dVal = 0; - - for (int i = 0; i < nRegs.Length; i++) - { - if (_monitorLastRegs[i] != nRegs[i]) - { - dVal = _monitorLastRegs[i] - nRegs[i]; - dCnt++; - } - } - - if (dCnt == 1 && - (dVal == 1 || dVal == -1)) - { - _monitorCount++; - - if (_monitorCount >= 16 && _autoPlay) - { - if (!_tapeIsPlaying) - { - Play(); - _machine.CPC.OSD_TapePlayingAuto(); - } - - _monitorTimeOut = 50; - } - } - else - { - _monitorCount = 0; - } - } - - _monitorLastRegs = nRegs; - _monitorLastPC = _cpu.RegPC; - } + public void AutoStopTape() { @@ -783,6 +683,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC _machine.CPC.OSD_TapePlayingAuto(); } + /* public int MaskableInterruptCount = 0; private void MonitorFrame() @@ -851,6 +752,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC } } } + */ #endregion @@ -866,15 +768,14 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// /// Device responds to an IN instruction /// - /// - /// /// - public bool ReadPort(ushort port, ref int result) + public bool ReadPort() { if (TapeIsPlaying) { GetEarBit(_cpu.TotalExecutedCycles); } + /* if (currentState) { result |= TAPE_BIT; @@ -883,55 +784,15 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC { result &= ~TAPE_BIT; } + */ if (!TapeIsPlaying) { - if (_machine.UPDDiskDevice == null || !_machine.UPDDiskDevice.FDD_IsDiskLoaded) - MonitorRead(); + //if (_machine.UPDDiskDevice == null || !_machine.UPDDiskDevice.FDD_IsDiskLoaded) + //MonitorRead(); } - if (_machine.UPDDiskDevice == null || !_machine.UPDDiskDevice.FDD_IsDiskLoaded) - MonitorRead(); - - /* - - if (TapeIsPlaying) - { - if (GetEarBit(_cpu.TotalExecutedCycles)) - { - result &= ~(TAPE_BIT); // reset is EAR ON - } - else - { - result |= (TAPE_BIT); // set is EAR Off - } - } - else - { - if (_machine.KeyboardDevice.IsIssue2Keyboard) - { - if ((_machine.LASTULAOutByte & (EAR_BIT + MIC_BIT)) == 0) - { - result &= ~(TAPE_BIT); - } - else - { - result |= (TAPE_BIT); - } - } - else - { - if ((_machine.LASTULAOutByte & EAR_BIT) == 0) - { - result &= ~(TAPE_BIT); - } - else - { - result |= TAPE_BIT; - } - } - } - - */ + //if (_machine.UPDDiskDevice == null || !_machine.UPDDiskDevice.FDD_IsDiskLoaded) + //MonitorRead(); return true; } @@ -939,17 +800,18 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// /// Device responds to an OUT instruction /// - /// - /// + /// /// - public bool WritePort(ushort port, int result) + public void WritePort(bool state) { + // not implemented + + /* if (!TapeIsPlaying) { currentState = ((byte)result & 0x10) != 0; } - - return true; + */ } #endregion @@ -970,12 +832,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC ser.Sync("_lastCycle", ref _lastCycle); ser.Sync("_waitEdge", ref _waitEdge); ser.Sync("currentState", ref currentState); - ser.Sync("_lastINCycle", ref _lastINCycle); - ser.Sync("_monitorCount", ref _monitorCount); - ser.Sync("_monitorTimeOut", ref _monitorTimeOut); - ser.Sync("_monitorLastPC", ref _monitorLastPC); - ser.Sync("_monitorLastRegs", ref _monitorLastRegs, false); - ser.Sync("TapeMotor", ref TapeMotor); + ser.Sync("TapeMotor", ref tapeMotor); ser.EndSection(); } diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/AmstradGateArray.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/AmstradGateArray.cs index 8b0ec2d3c8..0420f90167 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/AmstradGateArray.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/AmstradGateArray.cs @@ -168,6 +168,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC { _RMR = value; //ScreenMode = _RMR & 0x03; + var sm = _RMR & 0x03; + if (sm != 1) + { + + } if ((_RMR & 0x08) != 0) _machine.UpperROMPaged = false; @@ -254,7 +259,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// /// Master frame clock counter /// - private int FrameClock; + public int FrameClock; /// /// Simulates the gate array memory /WAIT line @@ -354,7 +359,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC // check for frame end if (FrameClock == FrameLength) { - FrameClock = 0; + //FrameClock = 0; FrameEnd = true; } } @@ -502,7 +507,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC // update screenmode ScreenMode = RMR & 0x03; CRT.CurrentLine.InitScanline(ScreenMode, VLC); - //CRT.InitScanline(VLC, ScreenMode); } else if (!CRCT.HSYNC) { @@ -786,6 +790,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC ser.Sync("CurrentPen", ref CurrentPen); ser.Sync("ClockCounter", ref ClockCounter); ser.Sync("FrameClock", ref FrameClock); + ser.Sync("FrameEnd", ref FrameEnd); ser.Sync("WaitLine", ref WaitLine); ser.Sync("_interruptCounter", ref _interruptCounter); ser.Sync("ScreenMode", ref ScreenMode); @@ -796,6 +801,12 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC ser.Sync("InterruptRaised", ref InterruptRaised); ser.Sync("InterruptHoldCounter", ref InterruptHoldCounter); ser.Sync("_MA", ref _MA); + ser.Sync("IsNewFrame", ref IsNewFrame); + ser.Sync("IsNewLine", ref IsNewLine); + ser.Sync("HCC", ref HCC); + ser.Sync("VLC", ref VLC); + ser.Sync("VideoByte1", ref VideoByte1); + ser.Sync("VideoByte2", ref VideoByte2); ser.EndSection(); } diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/CRCT_6845.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/CRCT_6845.cs index 82016ea13c..6a6ef8aed4 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/CRCT_6845.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/CRCT_6845.cs @@ -206,7 +206,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC public ushort CurrentByteAddress; /// - /// ByteCOunter + /// ByteCounter /// public int ByteCounter; @@ -890,6 +890,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC ser.Sync("VSYNC", ref VSYNC); ser.Sync("DISPTMG", ref DISPTMG); ser.Sync("MA", ref MA); + ser.Sync("CurrentByteAddress", ref CurrentByteAddress); + ser.Sync("ByteCounter", ref ByteCounter); ser.Sync("Regs", ref Regs, false); ser.Sync("SelectedRegister", ref SelectedRegister); ser.Sync("HCC", ref HCC); diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/CRTDevice.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/CRTDevice.cs index 36c0ddb53f..fc9faeb049 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/CRTDevice.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/Display/CRTDevice.cs @@ -231,7 +231,13 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC public void SyncState(Serializer ser) { - ser.BeginSection("CRT"); + ser.BeginSection("CRT"); + ser.Sync("BufferWidth", ref _bufferWidth); + ser.Sync("BufferHeight", ref _bufferHeight); + ser.Sync("VirtualHeight", ref _virtualHeight); + ser.Sync("VirtualWidth", ref _virtualWidth); + ser.Sync("ScreenBuffer", ref ScreenBuffer, false); + ser.Sync("ScanlineCounter", ref ScanlineCounter); ser.EndSection(); } @@ -322,7 +328,24 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC private void AddBorderValue(int charIndex, int colourValue) { Characters[charIndex].Phase = RenderPhase.BORDER; - Characters[charIndex].Pixels = new int[8]; + + switch (ScreenMode) + { + case 0: + Characters[charIndex].Pixels = new int[8]; + break; + case 1: + Characters[charIndex].Pixels = new int[8]; + break; + case 2: + Characters[charIndex].Pixels = new int[16]; + break; + case 3: + Characters[charIndex].Pixels = new int[8]; + break; + } + + for (int i = 0; i < Characters[charIndex].Pixels.Length; i++) { @@ -345,8 +368,9 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC switch (ScreenMode) { // 4 bits per pixel - 2 bytes - 4 pixels (8 CRT pixels) + // RECT case 0: - Characters[charIndex].Pixels = new int[4]; + Characters[charIndex].Pixels = new int[8]; int m0Count = 0; @@ -356,18 +380,23 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC int m0B0P1 = ((m0B0P1i & 0x40) >> 6) | ((m0B0P1i & 0x04) >> 1) | ((m0B0P1i & 0x10) >> 2) | ((m0B0P1i & 0x01 << 3)); Characters[charIndex].Pixels[m0Count++] = CRTDevice.CPCHardwarePalette[pens[m0B0P0]]; + Characters[charIndex].Pixels[m0Count++] = CRTDevice.CPCHardwarePalette[pens[m0B0P0]]; + Characters[charIndex].Pixels[m0Count++] = CRTDevice.CPCHardwarePalette[pens[m0B0P1]]; Characters[charIndex].Pixels[m0Count++] = CRTDevice.CPCHardwarePalette[pens[m0B0P1]]; - int m0B1P0i = vid1 & 170; + int m0B1P0i = vid2 & 170; int m0B1P0 = ((m0B1P0i & 0x80) >> 7) | ((m0B1P0i & 0x08) >> 2) | ((m0B1P0i & 0x20) >> 3) | ((m0B1P0i & 0x02 << 2)); - int m0B1P1i = vid1 & 85; + int m0B1P1i = vid2 & 85; int m0B1P1 = ((m0B1P1i & 0x40) >> 6) | ((m0B1P1i & 0x04) >> 1) | ((m0B1P1i & 0x10) >> 2) | ((m0B1P1i & 0x01 << 3)); Characters[charIndex].Pixels[m0Count++] = CRTDevice.CPCHardwarePalette[pens[m0B1P0]]; + Characters[charIndex].Pixels[m0Count++] = CRTDevice.CPCHardwarePalette[pens[m0B1P0]]; + Characters[charIndex].Pixels[m0Count++] = CRTDevice.CPCHardwarePalette[pens[m0B1P1]]; Characters[charIndex].Pixels[m0Count++] = CRTDevice.CPCHardwarePalette[pens[m0B1P1]]; break; // 2 bits per pixel - 2 bytes - 8 pixels (16 CRT pixels) + // SQUARE case 1: Characters[charIndex].Pixels = new int[8]; @@ -394,18 +423,21 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC Characters[charIndex].Pixels[m1Count++] = CRTDevice.CPCHardwarePalette[pens[m1B1P3]]; break; - // 1 bit per pixel - 2 bytes - 16 pixels (32 CRT pixels) + // 1 bit per pixel - 2 bytes - 16 pixels (16 CRT pixels) + // RECT case 2: Characters[charIndex].Pixels = new int[16]; int m2Count = 0; + int[] pixBuff = new int[16]; + for (int bit = 7; bit >= 0; bit--) { int val = vid1.Bit(bit) ? 1 : 0; Characters[charIndex].Pixels[m2Count++] = CRTDevice.CPCHardwarePalette[pens[val]]; - } + } for (int bit = 7; bit >= 0; bit--) { int val = vid2.Bit(bit) ? 1 : 0; @@ -414,6 +446,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC break; // 4 bits per pixel - 2 bytes - 4 pixels (8 CRT pixels) + // RECT case 3: Characters[charIndex].Pixels = new int[4]; @@ -460,8 +493,27 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// Processes and adds the scanline to the Screen Buffer /// public void CommitScanline() - { - int hPix = GetPixelCount() * 2; + { + int hScale = 1; + int vScale = 1; + + switch (ScreenMode) + { + case 0: + case 1: + case 3: + hScale = 2; + vScale = 2; + break; + + case 2: + hScale = 1; + vScale = 2; + break; + } + + int hPix = GetPixelCount() * hScale; + //int hPix = GetPixelCount() * 2; int leftOver = CRT.BufferWidth - hPix; int lPad = leftOver / 2; int rPad = lPad; @@ -477,8 +529,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC // render out the scanline int pCount = (LineIndex - CRT.TopLinesToTrim) * 2 * CRT.BufferWidth; - // double up - for (int s = 0; s < 2; s++) + // vScale + for (int s = 0; s < vScale; s++) { // left padding for (int lP = 0; lP < lPad; lP++) @@ -494,8 +546,13 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC for (int p = 0; p < c.Pixels.Length; p++) { - CRT.ScreenBuffer[pCount++] = c.Pixels[p]; - CRT.ScreenBuffer[pCount++] = c.Pixels[p]; + // hScale + for (int h = 0; h < hScale; h++) + { + CRT.ScreenBuffer[pCount++] = c.Pixels[p]; + } + + //CRT.ScreenBuffer[pCount++] = c.Pixels[p]; } } diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/SoundOutput/Beeper.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/SoundOutput/Beeper.cs index 586f79f3d3..27c8820c91 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/SoundOutput/Beeper.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Hardware/SoundOutput/Beeper.cs @@ -73,7 +73,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// /// Device blipbuffer /// - private readonly BlipBuffer blip = new BlipBuffer(882); + private readonly BlipBuffer blip = new BlipBuffer(1024); #endregion diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC464/CPC464.Port.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC464/CPC464.Port.cs index 6e69f0fee3..179e6909f8 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC464/CPC464.Port.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC464/CPC464.Port.cs @@ -56,56 +56,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC } return (byte)result; - - if ((port & 0x8000) == 0) - { - if ((port & 0x4000) != 0) - { - GateArray.ReadPort(port, ref result); - } - else - { - // ram - } - } - else if ((port & 0x4000) == 0) - { - CRCT.ReadPort(port, ref result); - } - else if ((port & 0x0300) == 0) - { - // rom - } - else if ((port & 0x1000) == 0) - { - // printer - } - else if ((port & 0x0800) == 0) - { - PPI.ReadPort(port, ref result); - } - else if ((port & 0x0400) == 0) - { - // exp - } - - return (byte)result; - - - if (CRCT.ReadPort(port, ref result)) - { - return (byte)result; - } - else if (PPI.ReadPort(port, ref result)) - { - return (byte)result; - } - else if (GateArray.ReadPort(port, ref result)) - { - return (byte)result; - } - - return (byte)result; } /// @@ -156,18 +106,6 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC } return; - - if (GateArray.WritePort(port, value)) - { } - - if (CRCT.WritePort(port, value)) - { } - - // rom select - // printer port - - if (PPI.WritePort(port, value)) - { } } } } diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC464/CPC464.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC464/CPC464.cs index 86649c995e..3c9cc04c2c 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC464/CPC464.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPC464/CPC464.cs @@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// /// /// - public CPC464(AmstradCPC cpc, Z80A cpu, List files) + public CPC464(AmstradCPC cpc, Z80A cpu, List files, bool autoTape) { CPC = cpc; CPU = cpu; @@ -37,7 +37,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC KeyboardDevice = new StandardKeyboard(this); - TapeDevice = new DatacorderDevice(); + TapeDevice = new DatacorderDevice(autoTape); TapeDevice.Init(this); InitializeMedia(files); diff --git a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs index dd4f1802ac..6ecbf15ca2 100644 --- a/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs +++ b/BizHawk.Emulation.Cores/Computers/AmstradCPC/Machine/CPCBase.cs @@ -109,7 +109,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC /// /// Gets the current frame cycle according to the CPU tick count /// - public virtual long CurrentFrameCycle => CPU.TotalExecutedCycles - LastFrameStartCPUTick; + public virtual long CurrentFrameCycle => GateArray.FrameClock; // CPU.TotalExecutedCycles - LastFrameStartCPUTick; /// /// Non-Deterministic bools @@ -170,10 +170,10 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC TapeDevice.TapeCycle(); } - OverFlow = (int)CurrentFrameCycle - GateArray.FrameLength; + //OverFlow = (int)CurrentFrameCycle - GateArray.FrameLength; // we have reached the end of a frame - LastFrameStartCPUTick = CPU.TotalExecutedCycles - OverFlow; + LastFrameStartCPUTick = CPU.TotalExecutedCycles; // - OverFlow; if (AYDevice != null) AYDevice.EndFrame(); @@ -199,6 +199,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC //System.IO.File.WriteAllText(UPDDiskDevice.outputfile, UPDDiskDevice.outputString); } } + + GateArray.FrameClock = 0; } #endregion @@ -334,14 +336,11 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC ser.Sync("RAM3", ref RAM3, false); CRCT.SyncState(ser); - - //KeyboardDevice.SyncState(ser); - //BuzzerDevice.SyncState(ser); + CRT.SyncState(ser); + GateArray.SyncState(ser); + KeyboardDevice.SyncState(ser); TapeBuzzer.SyncState(ser); - AYDevice.SyncState(ser); - //.SyncState(ser); - //CPUMon.SyncState(ser); ser.Sync("tapeMediaIndex", ref tapeMediaIndex); if (ser.IsReader)