protected void SynthSubchannelAsNeed(SectorSynthJob job)
        {
            //synth P if needed
            if ((job.Parts & ESectorSynthPart.SubchannelP) != 0)
            {
                SynthUtils.SubP(job.DestBuffer2448, job.DestOffset + 2352, Pause);
            }

            //synth Q if needed
            //TODO - why not already have it serialized? Into a disc resource, even.
            if ((job.Parts & ESectorSynthPart.SubchannelQ) != 0)
            {
                SynthUtils.SubQ_Serialize(job.DestBuffer2448, job.DestOffset + 2352 + 12, ref sq);
            }

            //clear R-W if needed
            if ((job.Parts & ESectorSynthPart.Subchannel_RSTUVW) != 0)
            {
                Array.Clear(job.DestBuffer2448, job.DestOffset + 2352 + 12 + 12, (12 * 6));
            }

            //subcode has been generated deinterleaved; we may still need to interleave it
            if ((job.Parts & ESectorSynthPart.SubcodeAny) != 0)
            {
                if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave)) == 0)
                {
                    SynthUtils.InterleaveSubcodeInplace(job.DestBuffer2448, job.DestOffset + 2352);
                }
            }
        }
Exemple #2
0
            public void Synth(SectorSynthJob job)
            {
                //CCD is always containing everything we'd need (unless a .sub is missing?) so don't worry about flags
                var imgBlob = job.Disc.DisposableResources[0] as IBlob;
                var subBlob = job.Disc.DisposableResources[1] as IBlob;

                //Read_2442(job.LBA, job.DestBuffer2448, job.DestOffset);

                //read the IMG data if needed
                if ((job.Parts & ESectorSynthPart.UserAny) != 0)
                {
                    long ofs = job.LBA * 2352;
                    imgBlob.Read(ofs, job.DestBuffer2448, 0, 2352);
                }

                //if subcode is needed, read it
                if ((job.Parts & (ESectorSynthPart.SubcodeAny)) != 0)
                {
                    long ofs = job.LBA * 96;
                    subBlob.Read(ofs, job.DestBuffer2448, 2352, 96);

                    //subcode comes to us deinterleved; we may still need to interleave it
                    if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave)) == 0)
                    {
                        SynthUtils.InterleaveSubcodeInplace(job.DestBuffer2448, job.DestOffset + 2352);
                    }
                }
            }
Exemple #3
0
            public void Synth(SectorSynthJob job)
            {
                //mednafen is always synthesizing everything, no need to worry about flags.. mostly./
                job.Params.MednaDisc.Read_2442(job.LBA, job.DestBuffer2448, job.DestOffset);

                //we may still need to deinterleave it if subcode was requested and it needs deinterleaving
                if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave | ESectorSynthPart.SubcodeAny)) != 0)
                {
                    SynthUtils.DeinterleaveSubcodeInplace(job.DestBuffer2448, 2352);
                }
            }
Exemple #4
0
        /// <summary>
        /// applies an SBI file to the disc
        /// </summary>
        public void Run(Disc disc, SBI.SubQPatchData sbi, bool asMednafen)
        {
            //TODO - could implement as a blob, to avoid allocating so many byte buffers

            //save this, it's small, and we'll want it for disc processing a/b checks
            disc.Memos["sbi"] = sbi;

            DiscSectorReader dsr = new DiscSectorReader(disc);

            int n = sbi.ABAs.Count;
            int b = 0;

            for (int i = 0; i < n; i++)
            {
                int lba = sbi.ABAs[i] - 150;

                //create a synthesizer which can return the patched data
                var ss_patchq = new SS_PatchQ {
                    Original = disc._Sectors[lba + 150]
                };
                byte[] subQbuf = ss_patchq.Buffer_SubQ;

                //read the old subcode
                dsr.ReadLBA_SubQ(lba, subQbuf, 0);

                //insert patch
                disc._Sectors[lba + 150] = ss_patchq;

                //apply SBI patch
                for (int j = 0; j < 12; j++)
                {
                    short patch = sbi.subq[b++];
                    if (patch == -1)
                    {
                        continue;
                    }
                    else
                    {
                        subQbuf[j] = (byte)patch;
                    }
                }

                //Apply mednafen hacks
                //The reasoning here is that we know we expect these sectors to have a wrong checksum. therefore, generate a checksum, and make it wrong
                //However, this seems senseless to me. The whole point of the SBI data is that it stores the patches needed to generate an acceptable subQ, right?
                if (asMednafen)
                {
                    SynthUtils.SubQ_SynthChecksum(subQbuf, 0);
                    subQbuf[10] ^= 0xFF;
                    subQbuf[11] ^= 0xFF;
                }
            }
        }
        public override void Synth(SectorSynthJob job)
        {
            //read the sector user data
            if ((job.Parts & ESectorSynthPart.User2048) != 0)
            {
                Blob.Read(BlobOffset, job.DestBuffer2448, job.DestOffset + 16, 2048);
            }

            if ((job.Parts & ESectorSynthPart.Header16) != 0)
            {
                SynthUtils.SectorHeader(job.DestBuffer2448, job.DestOffset + 0, job.LBA, 1);
            }

            if ((job.Parts & ESectorSynthPart.ECMAny) != 0)
            {
                SynthUtils.ECM_Mode1(job.DestBuffer2448, job.DestOffset + 0, job.LBA);
            }

            SynthSubchannelAsNeed(job);
        }
        public override void Synth(SectorSynthJob job)
        {
            //this isn't fully analyzed/optimized
            Array.Clear(job.DestBuffer2448, job.DestOffset, 2352);

            byte mode = 255;
            int  form = -1;

            switch (TrackType)
            {
            case CueTrackType.Audio:
                mode = 0;
                break;

            case CueTrackType.CDI_2352:
            case CueTrackType.Mode1_2352:
                mode = 1;
                break;

            case CueTrackType.Mode2_2352:
                mode = 2;
                if (Policy.CUE_PregapMode2_As_XA_Form2)
                {
                    job.DestBuffer2448[job.DestOffset + 12 + 6]  = 0x20;
                    job.DestBuffer2448[job.DestOffset + 12 + 10] = 0x20;
                }
                form = 2;                         //no other choice right now really
                break;

            case CueTrackType.Mode1_2048:
                mode  = 1;
                Pause = true;
                break;

            case CueTrackType.Mode2_2336:
            default:
                throw new InvalidOperationException("Not supported: " + TrackType);
            }

            //audio has no sector header but the others do
            if (mode != 0)
            {
                if ((job.Parts & ESectorSynthPart.Header16) != 0)
                {
                    SynthUtils.SectorHeader(job.DestBuffer2448, job.DestOffset + 0, job.LBA, mode);
                }
            }

            if (mode == 1)
            {
                if ((job.Parts & ESectorSynthPart.ECMAny) != 0)
                {
                    SynthUtils.ECM_Mode1(job.DestBuffer2448, job.DestOffset + 0, job.LBA);
                }
            }
            if (mode == 2 && form == 2)
            {
                SynthUtils.EDC_Mode2_Form2(job.DestBuffer2448, job.DestOffset);
            }

            SynthSubchannelAsNeed(job);
        }