From f7109d5f17a5398ed54cbb59b632e7d734fe8ee2 Mon Sep 17 00:00:00 2001 From: beirich Date: Thu, 15 Sep 2011 05:10:23 +0000 Subject: [PATCH] fix a stupid bug in pce-cd causing irqs to not be released --- BizHawk.Emulation/Consoles/PC Engine/ADPCM.cs | 5 +- .../Consoles/PC Engine/Compat.txt | 6 -- .../Consoles/PC Engine/PCEngine.cs | 9 +-- .../Consoles/PC Engine/ScsiCDBus.cs | 43 +++----------- .../Consoles/PC Engine/TurboCD.cs | 57 ++++++++++--------- BizHawk.MultiClient/MainForm.cs | 3 +- 6 files changed, 48 insertions(+), 75 deletions(-) diff --git a/BizHawk.Emulation/Consoles/PC Engine/ADPCM.cs b/BizHawk.Emulation/Consoles/PC Engine/ADPCM.cs index f3777190a1..f2fe269ef9 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/ADPCM.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/ADPCM.cs @@ -180,9 +180,8 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx } } - pce.IRQ2Monitor &= 0xF3; - if (HalfReached) pce.IRQ2Monitor |= 0x04; - if (EndReached) pce.IRQ2Monitor |= 0x08; + pce.IntADPCM = HalfReached; + pce.IntStop = EndReached; pce.RefreshIRQ2(); } diff --git a/BizHawk.Emulation/Consoles/PC Engine/Compat.txt b/BizHawk.Emulation/Consoles/PC Engine/Compat.txt index 19f4f72446..024f4d12d9 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/Compat.txt +++ b/BizHawk.Emulation/Consoles/PC Engine/Compat.txt @@ -7,16 +7,10 @@ - Dungeon Explorer II quite desperately need ADPCM audio + and a gross corruption issue at teh end of the intro. and then it freezes. :( -- Exile II .. seems to reset itself after playing the unskippable intro. :( -- Macross 2036.. seems impossible to start/play the game. :( - - Rayxanber 2 weird issues at the end of first level with cd audio player - Rtype, end of level 4 dies with unrecognized scsi command ff, or maybe freezes before then - Snatcher dies at startup while polling subcode, demonstrating the incorrectness of subcode polling code.. yeah that hangs together - Startling Odyssey does the reset-at-new-game-screen thats rather odd :( -- Super Darius II : at 1st Boss, game freezes waiting for adpcm -- Ys 1, start new game, death by adpcm probably ** shit it works now. - card angels does poll subcode... diff --git a/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs b/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs index a27cd35337..37d39c9871 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs @@ -72,11 +72,11 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx void Init(GameInfo game, byte[] rom) { Controller = NullController.GetNullController(); - Cpu = new HuC6280(); - VCE = new VCE(); + Cpu = new HuC6280(); + VCE = new VCE(); VDC1 = new VDC(Cpu, VCE); - PSG = new HuC6280PSG(); - InitScsiBus(); + PSG = new HuC6280PSG(); + SCSI = new ScsiCDBus(this, disc); if (TurboGrafx) { @@ -109,6 +109,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx Cpu.WriteMemory21 = WriteMemoryCD; Cpu.WriteVDC = VDC1.WriteVDC; CDAudio = new CDAudio(disc); + SetCDAudioCallback(); PSG.MaxVolume = short.MaxValue * 3 / 4; SoundMixer = new SoundMixer(PSG, CDAudio, ADPCM); SoundSynchronizer = new MetaspuSoundProvider(ESynchMethod.ESynchMethod_V); diff --git a/BizHawk.Emulation/Consoles/PC Engine/ScsiCDBus.cs b/BizHawk.Emulation/Consoles/PC Engine/ScsiCDBus.cs index db3206ad89..5bf0c98da3 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/ScsiCDBus.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/ScsiCDBus.cs @@ -4,6 +4,10 @@ using BizHawk.Emulation.Sound; namespace BizHawk.Emulation.Consoles.TurboGrafx { + // TODO we can adjust this to have Think take the number of cycles and not require + // a reference to Cpu.TotalExecutedCycles + // which incidentally would allow us to put it back to an int from a long if we wanted to + public sealed class ScsiCDBus { const int STATUS_GOOD = 0; @@ -141,11 +145,6 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx PCEngine pce; public Disc disc; - // ******** Events ******** - - public Action DataTransferReady; - public Action DataTransferComplete; - public ScsiCDBus(PCEngine pce, Disc disc) { this.pce = pce; @@ -171,7 +170,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx CurrentReadingSector++; SectorsLeftToRead--; - DataTransferReady(true); + pce.IntDataTransferReady = true; // If more sectors, should set the next think-clock to however long it takes to read 1 sector // but I dont. I dont think transfers actually happen sector by sector @@ -273,13 +272,13 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx } else { // data transfer is finished - DataTransferReady(false); + pce.IntDataTransferReady = false; if (DataTransferWasDone) { Console.WriteLine("DATA TRANSFER FINISHED!"); DataTransferInProgress = false; DataTransferWasDone = false; - DataTransferComplete(true); + pce.IntDataTransferComplete = true; } SetStatusMessage(STATUS_GOOD, 0); } @@ -404,7 +403,6 @@ throw new Exception("requesting 0 sectors read............................."); { case 0x00: // Set start offset in LBA units audioStartLBA = (CommandBuffer[3] << 16) | (CommandBuffer[4] << 8) | CommandBuffer[5]; - //Console.WriteLine("Set Start LBA: "+audioStartLBA); break; case 0x40: // Set start offset in MSF units @@ -412,30 +410,22 @@ throw new Exception("requesting 0 sectors read............................."); byte s = CommandBuffer[3].BCDtoBin(); byte f = CommandBuffer[4].BCDtoBin(); audioStartLBA = Disc.ConvertMSFtoLBA(m, s, f); - //Console.WriteLine("Set Start MSF: {0} {1} {2} lba={3}",m,s,f,audioStartLBA); break; case 0x80: // Set start offset in track units byte trackNo = CommandBuffer[2].BCDtoBin(); audioStartLBA = disc.TOC.Sessions[0].Tracks[trackNo - 1].Indexes[1].aba - 150; - //Console.WriteLine("Set Start track: {0} lba={1}", trackNo, audioStartLBA); break; } if (CommandBuffer[1] == 0) { pce.CDAudio.Pause(); - // silent? } else { pce.CDAudio.PlayStartingAtLba(audioStartLBA); } - - // TODO there are some flags in command[1] - // wat we do if audio is already playing - // wat we do if audio paused SetStatusMessage(STATUS_GOOD, 0); - // irq callback? } void CommandAudioEndPos() @@ -444,7 +434,6 @@ throw new Exception("requesting 0 sectors read............................."); { case 0x00: // Set end offset in LBA units audioEndLBA = (CommandBuffer[3] << 16) | (CommandBuffer[4] << 8) | CommandBuffer[5]; - //Console.WriteLine("Set End LBA: " + audioEndLBA); break; case 0x40: // Set end offset in MSF units @@ -452,7 +441,6 @@ throw new Exception("requesting 0 sectors read............................."); byte s = CommandBuffer[3].BCDtoBin(); byte f = CommandBuffer[4].BCDtoBin(); audioEndLBA = Disc.ConvertMSFtoLBA(m, s, f); - //Console.WriteLine("Set End MSF: {0} {1} {2} lba={3}", m, s, f, audioEndLBA); break; case 0x80: // Set end offset in track units @@ -461,7 +449,6 @@ throw new Exception("requesting 0 sectors read............................."); audioEndLBA = disc.LBACount; else audioEndLBA = disc.TOC.Sessions[0].Tracks[trackNo - 1].Indexes[1].aba - 150; - //Console.WriteLine("Set End track: {0} lba={1}", trackNo, audioEndLBA); break; } @@ -471,19 +458,17 @@ throw new Exception("requesting 0 sectors read............................."); pce.CDAudio.Stop(); break; case 1: // play in loop mode. I guess this constitues A-B looping - //Console.WriteLine("DOING A-B LOOP. NOT SURE IF RIGHT."); pce.CDAudio.PlayStartingAtLba(audioStartLBA); pce.CDAudio.EndLBA = audioEndLBA; pce.CDAudio.PlayMode = CDAudio.PlaybackMode.LoopOnCompletion; break; case 2: // Play audio, fire IRQ2 when end position reached - Console.WriteLine("STOP MODE 2 ENGAGED, BUT NOTE. IRQ WILL NOT FIRE YET."); + Console.WriteLine("***********STOP MODE 2 ENGAGED. IT IS CONCEIVABLE THAT IRQ WILL FIRE."); pce.CDAudio.PlayStartingAtLba(audioStartLBA); pce.CDAudio.EndLBA = audioEndLBA; pce.CDAudio.PlayMode = CDAudio.PlaybackMode.CallbackOnCompletion; break; case 3: // Play normal - //Console.WriteLine("*** SET END POS, IN PLAY NORMAL MODE? STARTING AT _START_ POS. IS THAT RIGHT?"); pce.CDAudio.PlayStartingAtLba(audioStartLBA); pce.CDAudio.EndLBA = audioEndLBA; pce.CDAudio.PlayMode = CDAudio.PlaybackMode.StopOnCompletion; @@ -494,10 +479,8 @@ throw new Exception("requesting 0 sectors read............................."); void CommandPause() { - // apparently pause means stop? I guess? Idunno. pce.CDAudio.Stop(); SetStatusMessage(STATUS_GOOD, 0); - // TODO send error if already stopped.. or paused... or something. } void CommandReadSubcodeQ() @@ -535,7 +518,6 @@ throw new Exception("requesting 0 sectors read............................."); { case 0: // return number of tracks { - //Log.Error("CD","Execute READ_TOC : num of tracks"); DataIn.Clear(); DataIn.Enqueue(0x01); DataIn.Enqueue(((byte) disc.TOC.Sessions[0].Tracks.Count).BinToBCD()); @@ -554,9 +536,6 @@ throw new Exception("requesting 0 sectors read............................."); DataIn.Enqueue(s.BinToBCD()); DataIn.Enqueue(f.BinToBCD()); SetPhase(BusPhase.DataIn); - - //Log.Error("CD","EXECUTE READ_TOC : length of disc, LBA {0}, m:{1},s:{2},f:{3}", - //totalLbaLength, m, s, f); break; } case 2: // Return starting position of specified track in MSF format @@ -583,10 +562,6 @@ throw new Exception("requesting 0 sectors read............................."); else DataIn.Enqueue(4); SetPhase(BusPhase.DataIn); - - //Log.Error("CD", "EXECUTE READ_TOC : start pos of TRACK {4}, LBA {0}, m:{1},s:{2},f:{3}", - //lbaPos, m, s, f, track); - break; } default: @@ -620,7 +595,7 @@ throw new Exception("requesting 0 sectors read............................."); CD = false; IO = false; REQ = false; - DataTransferComplete(false); + pce.IntDataTransferComplete = false; break; case BusPhase.Command: BSY = true; diff --git a/BizHawk.Emulation/Consoles/PC Engine/TurboCD.cs b/BizHawk.Emulation/Consoles/PC Engine/TurboCD.cs index 1bb14e8899..4b864bb7de 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/TurboCD.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/TurboCD.cs @@ -1,12 +1,5 @@ using System; -// IRQ2 interrupts: -// 0x04 - INTA - ADPCM interrupt / Half Reached -// 0x08 - INTSTOP - Fire when end of CD-Audio playback reached when in STOP MODE 2. -// 0x10 - INTSUB - something with subchannel -// 0x20 - INTM - Fires when data transfer is complete -// 0x40 - INTD - Fires when data transfer is ready - namespace BizHawk.Emulation.Consoles.TurboGrafx { public partial class PCEngine @@ -16,6 +9,32 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx public byte IRQ2Control { get { return CdIoPorts[2]; } set { CdIoPorts[2] = value; } } public byte IRQ2Monitor { get { return CdIoPorts[3]; } set { CdIoPorts[3] = value; } } + public bool IntADPCM // INTA + { + get { return (CdIoPorts[3] & 0x04) != 0; } + set { CdIoPorts[3] = (byte)((CdIoPorts[3] & ~0x04) | (value ? 0x04 : 0x00)); } + } + public bool IntStop // INTSTOP + { + get { return (CdIoPorts[3] & 0x08) != 0; } + set { CdIoPorts[3] = (byte)((CdIoPorts[3] & ~0x08) | (value ? 0x8 : 0x00)); } + } + public bool IntSubchannel // INTSUB + { + get { return (CdIoPorts[3] & 0x10) != 0; } + set { CdIoPorts[3] = (byte)((CdIoPorts[3] & ~0x10) | (value ? 0x10 : 0x00)); } + } + public bool IntDataTransferComplete // INTM + { + get { return (CdIoPorts[3] & 0x20) != 0; } + set { CdIoPorts[3] = (byte)((CdIoPorts[3] & ~0x20) | (value ? 0x20 : 0x00)); } + } + public bool IntDataTransferReady // INTD + { + get { return (CdIoPorts[3] & 0x40) != 0; } + set { CdIoPorts[3] = (byte)((CdIoPorts[3] & ~0x40) | (value ? 0x40 : 0x00)); } + } + public byte Port1803 { get { return CdIoPorts[3]; } @@ -27,27 +46,13 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx } } - void InitScsiBus() + void SetCDAudioCallback() { - SCSI = new ScsiCDBus(this, disc); - // this is kind of stupid - SCSI.DataTransferReady = yes => - { - // set or clear Ready Bit - if (yes) - Port1803 |= 0x40; - else - Port1803 &= 0xBF; - }; - SCSI.DataTransferComplete = yes => + CDAudio.CallbackAction = () => { - if (yes) - Port1803 |= 0x20; // Set "Complete" - else - { - Port1803 &= 0xBF; // Clear "ready" - } - + Console.WriteLine("FIRING CD-AUDIO STOP IRQ MAYBE!"); + IntDataTransferReady = false; + IntDataTransferComplete = true; }; } diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index 0b4a1100e4..2084d5df54 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -338,8 +338,7 @@ namespace BizHawk.MultiClient StepRunLoop_Core(); - if (!IsNullEmulator()) - StepRunLoop_Throttle(); + StepRunLoop_Throttle(); Render();