Example #1
0
        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;
            }
        }
Example #2
0
        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();
            }
        }
Example #3
0
        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);
            }
        }