Ejemplo n.º 1
0
        public void Synth(SectorSynthJob job)
        {
            //be lazy, just generate the whole sector unconditionally
            //this is mostly based on mednafen's approach, which was probably finely tailored for PSX
            //heres the comments on the subject:
            //  I'm not trusting that the "control" field for the TOC leadout entry will always be set properly, so | the control fields for the last track entry
            //  and the leadout entry together before extracting the D2 bit.  Audio track->data leadout is fairly benign though maybe noisy(especially if we ever implement
            //  data scrambling properly), but data track->audio leadout could break things in an insidious manner for the more accurate drive emulation code).

            var ses          = job.Disc.Structure.Sessions[SessionNumber];
            int lba_relative = job.LBA - ses.LeadoutTrack.LBA;

            //data is zero

            int ts  = lba_relative;
            int ats = job.LBA;

            const int ADR     = 0x1;         // Q channel data encodes position
            EControlQ control = ses.LeadoutTrack.Control;

            //ehhh? CDI?
            //if(toc.tracks[toc.last_track].valid)
            // control |= toc.tracks[toc.last_track].control & 0x4;
            //else if(toc.disc_type == DISC_TYPE_CD_I)
            // control |= 0x4;
            control |= (EControlQ)(((int)ses.LastInformationTrack.Control) & 4);

            SubchannelQ sq = new SubchannelQ();

            sq.SetStatus(ADR, control);
            sq.q_tno.BCDValue   = 0xAA;
            sq.q_index.BCDValue = 0x01;
            sq.Timestamp        = ts;
            sq.AP_Timestamp     = ats;
            sq.zero             = 0;

            //finally, rely on a gap sector to do the heavy lifting to synthesize this
            CUE.CueTrackType TrackType = CUE.CueTrackType.Audio;
            if (ses.LeadoutTrack.IsData)
            {
                if (job.Disc.TOC.Session1Format == SessionFormat.Type20_CDXA || job.Disc.TOC.Session1Format == SessionFormat.Type10_CDI)
                {
                    TrackType = CUE.CueTrackType.Mode2_2352;
                }
                else
                {
                    TrackType = CUE.CueTrackType.Mode1_2352;
                }
            }

            CUE.SS_Gap ss_gap = new CUE.SS_Gap()
            {
                Policy    = Policy,
                sq        = sq,
                TrackType = TrackType,
                Pause     = true             //?
            };

            ss_gap.Synth(job);
        }
        /// <summary>appends the new entries to the provided list</summary>
        /// <exception cref="InvalidOperationException"><see cref="IN_Session1Format"/> is <see cref="SessionFormat.None"/> or a non-member</exception>
        public void Run(List <RawTOCEntry> entries)
        {
            //NOTE: entries are inserted at the beginning due to observations of CCD indicating they might need to be that way
            //Since I'm being asked to synthesize them here, I guess I can put them in whatever order I want, can't I?

            SubchannelQ sq = new SubchannelQ();

            //ADR (q-Mode) is necessarily 0x01 for a RawTOCEntry
            const int kADR            = 1;
            const int kUnknownControl = 0;

            sq.SetStatus(kADR, (EControlQ)kUnknownControl);

            //first recorded track number:
            sq.q_index.BCDValue    = 0xA0;
            sq.ap_min.DecimalValue = IN_FirstRecordedTrackNumber;
            switch (IN_Session1Format)
            {
            //TODO these probably shouldn't be decimal values
            case SessionFormat.Type00_CDROM_CDDA: sq.ap_sec.DecimalValue = 0x00; break;

            case SessionFormat.Type10_CDI: sq.ap_sec.DecimalValue = 0x10; break;

            case SessionFormat.Type20_CDXA: sq.ap_sec.DecimalValue = 0x20; break;

            default: throw new InvalidOperationException("Invalid Session1Format");
            }
            sq.ap_frame.DecimalValue = 0;

            entries.Insert(0, new RawTOCEntry {
                QData = sq
            });

            //last recorded track number:
            sq.q_index.BCDValue      = 0xA1;
            sq.ap_min.DecimalValue   = IN_LastRecordedTrackNumber;
            sq.ap_sec.DecimalValue   = 0;
            sq.ap_frame.DecimalValue = 0;

            entries.Insert(1, new RawTOCEntry {
                QData = sq
            });

            //leadout:
            sq.q_index.BCDValue = 0xA2;
            sq.AP_Timestamp     = IN_LeadoutTimestamp;

            entries.Insert(2, new RawTOCEntry {
                QData = sq
            });
        }
Ejemplo n.º 3
0
		/// <summary>
		/// Appends the new entries to the provided list
		/// </summary>
		public void Run(List<RawTOCEntry> entries)
		{
			//NOTE: entries are inserted at the beginning due to observations of CCD indicating they might need to be that way
			//Since I'm being asked to synthesize them here, I guess I can put them in whatever order I want, can't I?

			SubchannelQ sq = new SubchannelQ();

			//ADR (q-Mode) is necessarily 0x01 for a RawTOCEntry
			const int kADR = 1;
			const int kUnknownControl = 0;

			sq.SetStatus(kADR, (EControlQ)kUnknownControl);

			//first recorded track number:
			sq.q_index.BCDValue = 0xA0;
			sq.ap_min.DecimalValue = IN_FirstRecordedTrackNumber;
			switch(IN_Session1Format)
			{
				//TODO these probably shouldn't be decimal values
				case SessionFormat.Type00_CDROM_CDDA: sq.ap_sec.DecimalValue = 0x00; break;
				case SessionFormat.Type10_CDI: sq.ap_sec.DecimalValue = 0x10; break;
				case SessionFormat.Type20_CDXA: sq.ap_sec.DecimalValue = 0x20; break;
				default: throw new InvalidOperationException("Invalid Session1Format");
			}
			sq.ap_frame.DecimalValue = 0;

			entries.Insert(0, new RawTOCEntry { QData = sq });

			//last recorded track number:
			sq.q_index.BCDValue = 0xA1;
			sq.ap_min.DecimalValue = IN_LastRecordedTrackNumber;
			sq.ap_sec.DecimalValue = 0;
			sq.ap_frame.DecimalValue = 0;

			entries.Insert(1, new RawTOCEntry { QData = sq });

			//leadout:
			sq.q_index.BCDValue = 0xA2;
			sq.AP_Timestamp = IN_LeadoutTimestamp;

			entries.Insert(2, new RawTOCEntry { QData = sq });
		}
Ejemplo n.º 4
0
        public void Run()
        {
            //TODO: encode_mode2_form2_sector

            var leadoutTs = Disc.TOC.LeadoutLBA;
            var lastTrackTOCItem = Disc.TOC.TOCItems[Disc.TOC.LastRecordedTrackNumber]; //NOTE: in case LastRecordedTrackNumber is al ie, this will malfunction

            //leadout flags.. let's set them the same as the last track.
            //THIS IS NOT EXACTLY THE SAME WAY MEDNAFEN DOES IT
            EControlQ leadoutFlags = lastTrackTOCItem.Control;

            //TODO - needs to be encoded as a certain mode (mode 2 form 2 for psx... i guess...)

            for (int i = 0; i < Length; i++)
            {
                //var se = new SectorEntry(sz);
                //Disc.Sectors.Add(se);
                SubchannelQ sq = new SubchannelQ();

                int track_relative_msf = i;
                sq.min = BCD2.FromDecimal(new Timestamp(track_relative_msf).MIN);
                sq.sec = BCD2.FromDecimal(new Timestamp(track_relative_msf).SEC);
                sq.frame = BCD2.FromDecimal(new Timestamp(track_relative_msf).FRAC);

                int absolute_msf = i + leadoutTs.Sector;
                sq.ap_min = BCD2.FromDecimal(new Timestamp(absolute_msf + 150).MIN);
                sq.ap_sec = BCD2.FromDecimal(new Timestamp(absolute_msf + 150).SEC);
                sq.ap_frame = BCD2.FromDecimal(new Timestamp(absolute_msf + 150).FRAC);

                sq.q_tno.DecimalValue = 0xAA; //special value for leadout
                sq.q_index.DecimalValue = 1;

                byte ADR = 1;
                sq.SetStatus(ADR, leadoutFlags);

                //TODO - actually stash the subQ
            }
        }
Ejemplo n.º 5
0
        public void Run()
        {
            //TODO: encode_mode2_form2_sector

            var leadoutTs        = Disc.TOC.LeadoutLBA;
            var lastTrackTOCItem = Disc.TOC.TOCItems[Disc.TOC.LastRecordedTrackNumber];             //NOTE: in case LastRecordedTrackNumber is al ie, this will malfunction

            //leadout flags.. let's set them the same as the last track.
            //THIS IS NOT EXACTLY THE SAME WAY MEDNAFEN DOES IT
            EControlQ leadoutFlags = lastTrackTOCItem.Control;

            //TODO - needs to be encoded as a certain mode (mode 2 form 2 for psx... i guess...)

            for (int i = 0; i < Length; i++)
            {
                //var se = new SectorEntry(sz);
                //Disc.Sectors.Add(se);
                SubchannelQ sq = new SubchannelQ();

                int track_relative_msf = i;
                sq.min   = BCD2.FromDecimal(new Timestamp(track_relative_msf).MIN);
                sq.sec   = BCD2.FromDecimal(new Timestamp(track_relative_msf).SEC);
                sq.frame = BCD2.FromDecimal(new Timestamp(track_relative_msf).FRAC);

                int absolute_msf = i + leadoutTs;
                sq.ap_min   = BCD2.FromDecimal(new Timestamp(absolute_msf + 150).MIN);
                sq.ap_sec   = BCD2.FromDecimal(new Timestamp(absolute_msf + 150).SEC);
                sq.ap_frame = BCD2.FromDecimal(new Timestamp(absolute_msf + 150).FRAC);

                sq.q_tno.DecimalValue   = 0xAA;               //special value for leadout
                sq.q_index.DecimalValue = 1;

                byte ADR = 1;
                sq.SetStatus(ADR, leadoutFlags);

                //TODO - actually stash the subQ
            }
        }
Ejemplo n.º 6
0
        public void Synth(SectorSynthJob job)
        {
            //be lazy, just generate the whole sector unconditionally
            //this is mostly based on mednafen's approach, which was probably finely tailored for PSX
            //heres the comments on the subject:
            //  I'm not trusting that the "control" field for the TOC leadout entry will always be set properly, so | the control fields for the last track entry
            //  and the leadout entry together before extracting the D2 bit.  Audio track->data leadout is fairly benign though maybe noisy(especially if we ever implement
            //  data scrambling properly), but data track->audio leadout could break things in an insidious manner for the more accurate drive emulation code).

            var ses = job.Disc.Structure.Sessions[SessionNumber];
            int lba_relative = job.LBA - ses.LeadoutTrack.LBA;

            //data is zero

            int ts = lba_relative;
            int ats = job.LBA;

            const int ADR = 0x1; // Q channel data encodes position
            EControlQ control = ses.LeadoutTrack.Control;

            //ehhh? CDI?
             //if(toc.tracks[toc.last_track].valid)
             // control |= toc.tracks[toc.last_track].control & 0x4;
             //else if(toc.disc_type == DISC_TYPE_CD_I)
             // control |= 0x4;
            control |= (EControlQ)(((int)ses.LastInformationTrack.Control) & 4);

            SubchannelQ sq = new SubchannelQ();
            sq.SetStatus(ADR, control);
            sq.q_tno.BCDValue = 0xAA;
            sq.q_index.BCDValue = 0x01;
            sq.Timestamp = ts;
            sq.AP_Timestamp = ats;
            sq.zero = 0;

            //finally, rely on a gap sector to do the heavy lifting to synthesize this
            CUE.CueTrackType TrackType = CUE.CueTrackType.Audio;
            if (ses.LeadoutTrack.IsData)
            {
                if (job.Disc.TOC.Session1Format == SessionFormat.Type20_CDXA || job.Disc.TOC.Session1Format == SessionFormat.Type10_CDI)
                    TrackType = CUE.CueTrackType.Mode2_2352;
                else
                    TrackType = CUE.CueTrackType.Mode1_2352;
            }

            CUE.SS_Gap ss_gap = new CUE.SS_Gap()
            {
                Policy = Policy,
                sq = sq,
                TrackType = TrackType,
                Pause = true //?
            };

            ss_gap.Synth(job);
        }