void WriteCD(int addr, byte value) { if (!TurboCD && !BramEnabled) { return; // flee if no turboCD hooked up } if (!TurboCD && addr != 0x1FF807) { return; // only bram port available unless full TurobCD mode. } switch (addr & 0x1FFF) { case 0x1800: // SCSI Drive Control Line CdIoPorts[0] = value; SCSI.SEL = true; SCSI.Think(); SCSI.SEL = false; SCSI.Think(); break; case 0x1801: // CDC Command CdIoPorts[1] = value; SCSI.DataBits = value; SCSI.Think(); break; case 0x1802: // ACK and Interrupt Control CdIoPorts[2] = value; SCSI.ACK = ((value & 0x80) != 0); SCSI.Think(); RefreshIRQ2(); break; case 0x1804: // CD Reset Command CdIoPorts[4] = value; SCSI.RST = ((value & 0x02) != 0); SCSI.Think(); if (SCSI.RST) { CdIoPorts[3] &= 0x8F; // Clear interrupt control bits RefreshIRQ2(); } break; case 0x1805: case 0x1806: // Latch CDDA data... no action needed for us (because we cheat) break; case 0x1807: // BRAM Unlock if (BramEnabled && (value & 0x80) != 0) { BramLocked = false; } break; case 0x1808: // ADPCM address LSB ADPCM.IOAddress &= 0xFF00; ADPCM.IOAddress |= value; if ((CdIoPorts[0x0D] & 0x10) != 0) { Console.WriteLine("doing silly thing"); } break; case 0x1809: // ADPCM address MSB ADPCM.IOAddress &= 0x00FF; ADPCM.IOAddress |= (ushort)(value << 8); if ((CdIoPorts[0x0D] & 0x10) != 0) { Console.WriteLine("doing silly thing"); } break; case 0x180A: // ADPCM Memory Read/Write Port ADPCM.Port180A = value; break; case 0x180B: // ADPCM DMA Control ADPCM.Port180B = value; break; case 0x180D: // ADPCM Address Control ADPCM.AdpcmControlWrite(value); break; case 0x180E: // ADPCM Playback Rate ADPCM.Port180E = value; break; case 0x180F: // Audio Fade Timer CdIoPorts[0x0F] = value; // TODO ADPCM fades/vol control also. switch (value) { case 0: CDAudio.LogicalVolume = 100; break; case 8: case 9: if (CDAudio.FadeOutFramesRemaining == 0) { CDAudio.FadeOut(360); // 6 seconds } break; case 12: case 13: if (CDAudio.FadeOutFramesRemaining == 0) { CDAudio.FadeOut(120); // 2 seconds } break; } break; // Arcade Card ports case 0x1AE0: ShiftRegister &= ~0xFF; ShiftRegister |= value; break; case 0x1AE1: ShiftRegister &= ~0xFF00; ShiftRegister |= value << 8; break; case 0x1AE2: ShiftRegister &= ~0xFF0000; ShiftRegister |= value << 16; break; case 0x1AE3: ShiftRegister &= 0xFFFFFF; ShiftRegister |= value << 24; break; case 0x1AE4: ShiftAmount = (byte)(value & 0x0F); if (ShiftAmount != 0) { if ((ShiftAmount & 8) != 0) { ShiftRegister >>= 16 - ShiftAmount; } else { ShiftRegister <<= ShiftAmount; } } break; case 0x1AE5: RotateAmount = value; // rotate not implemented, as no test case exists break; default: if (addr >= 0x1FFA00 && addr < 0x1FFA40) { WriteArcadeCard(addr & 0x1FFF, value); } else { Log.Error("CD", "unknown write to {0:X4}:{1:X2} pc={2:X4}", addr, value, Cpu.PC); } break; } }
private void SyncState(Serializer ser) { ser.BeginSection("PCEngine"); Cpu.SyncState(ser); VCE.SyncState(ser); VDC1.SyncState(ser, 1); PSG.SyncState(ser); if (SuperGrafx) { VPC.SyncState(ser); VDC2.SyncState(ser, 2); } if (TurboCD) { ADPCM.SyncState(ser); CDAudio.SyncState(ser); SCSI.SyncState(ser); ser.Sync("CDRAM", ref CDRam, false); if (SuperRam != null) { ser.Sync("SuperRAM", ref SuperRam, false); } if (ArcadeCard) { ArcadeCardSyncState(ser); } } ser.Sync("RAM", ref Ram, false); ser.Sync("IOBuffer", ref IOBuffer); ser.Sync("CdIoPorts", ref CdIoPorts, false); ser.Sync("BramLocked", ref BramLocked); ser.Sync("Frame", ref frame); ser.Sync("Lag", ref _lagCount); ser.Sync("IsLag", ref _isLag); if (Cpu.ReadMemory21 == ReadMemorySF2) { ser.Sync("SF2MapperLatch", ref SF2MapperLatch); } if (PopulousRAM != null) { ser.Sync("PopulousRAM", ref PopulousRAM, false); } if (BRAM != null) { ser.Sync("BRAM", ref BRAM, false); } ser.EndSection(); if (ser.IsReader) { SyncAllByteArrayDomains(); } }
public byte ReadCD(int addr) { if (!TurboCD && !BramEnabled) { return(0xFF); //bail if no TurboCD. } if (!TurboCD && addr != 0x1FF803) // only allow access to $1803 unless full TurboCD mode. { return(0xFF); } byte returnValue = 0; short sample; switch (addr & 0x1FFF) { case 0x1800: // SCSI Drive Control Line if (SCSI.IO) { returnValue |= 0x08; } if (SCSI.CD) { returnValue |= 0x10; } if (SCSI.MSG) { returnValue |= 0x20; } if (SCSI.REQ) { returnValue |= 0x40; } if (SCSI.BSY) { returnValue |= 0x80; } return(returnValue); case 0x1801: // Read data bus return(SCSI.DataBits); case 0x1802: // ADPCM / CD Control return(CdIoPorts[2]); case 0x1803: // BRAM Lock if (BramEnabled) { BramLocked = true; } returnValue = CdIoPorts[3]; CdIoPorts[3] ^= 2; return(returnValue); case 0x1804: // CD Reset return(CdIoPorts[4]); case 0x1805: // CD audio data Low if ((CdIoPorts[3] & 0x2) == 0) { sample = CDAudio.VolumeLeft; } else { sample = CDAudio.VolumeRight; } return((byte)sample); case 0x1806: // CD audio data High if ((CdIoPorts[3] & 0x2) == 0) { sample = CDAudio.VolumeLeft; } else { sample = CDAudio.VolumeRight; } return((byte)(sample >> 8)); case 0x1808: // Auto Handshake Data Input returnValue = SCSI.DataBits; if (SCSI.REQ && SCSI.IO && !SCSI.CD) { SCSI.ACK = false; SCSI.REQ = false; SCSI.Think(); } return(returnValue); case 0x180A: // ADPCM Memory Read/Write Port return(ADPCM.Port180A); case 0x180B: // ADPCM Data Transfer Control return(ADPCM.Port180B); case 0x180C: // ADPCM Status returnValue = 0; if (ADPCM.EndReached) { returnValue |= 0x01; } if (ADPCM.AdpcmIsPlaying) { returnValue |= 0x08; } if (ADPCM.AdpcmBusyWriting) { returnValue |= 0x04; } if (ADPCM.AdpcmBusyReading) { returnValue |= 0x80; } //Log.Error("CD", "Read ADPCM Status {0:X2}", returnValue); return(returnValue); case 0x180D: // ADPCM Play Control return(CdIoPorts[0x0D]); case 0x180F: // Audio Fade Timer return(CdIoPorts[0x0F]); // These are some retarded version check case 0x18C1: return(0xAA); case 0x18C2: return(0x55); case 0x18C3: return(0x00); case 0x18C5: return(0xAA); case 0x18C6: return(0x55); case 0x18C7: return(0x03); // Arcade Card ports case 0x1AE0: return(ArcadeCard ? (byte)(ShiftRegister >> 0) : (byte)0xFF); case 0x1AE1: return(ArcadeCard ? (byte)(ShiftRegister >> 8) : (byte)0xFF); case 0x1AE2: return(ArcadeCard ? (byte)(ShiftRegister >> 16) : (byte)0xFF); case 0x1AE3: return(ArcadeCard ? (byte)(ShiftRegister >> 24) : (byte)0xFF); case 0x1AE4: return(ArcadeCard ? ShiftAmount : (byte)0xFF); case 0x1AE5: return(ArcadeCard ? RotateAmount : (byte)0xFF); case 0x1AFE: return(ArcadeCard ? (byte)0x10 : (byte)0xFF); case 0x1AFF: return(ArcadeCard ? (byte)0x51 : (byte)0xFF); default: if (addr >= 0x1FFA00 && addr < 0x1FFA40) { return(ReadArcadeCard(addr & 0x1FFF)); } else { Log.Error("CD", "unknown read to {0:X4}", addr); } return(0xFF); } }