Beispiel #1
0
        /// <summary>
        /// Reads 12 bytes of subQ data from a sector and stores it unpacked into the provided struct
        /// TODO - make use of deserialize code elsewhere
        /// </summary>
        public void ReadLBA_SubQ(int lba, out SubchannelQ sq)
        {
            ReadLBA_SubQ(lba, buf12, 0);

            sq.q_status          = buf12[0];
            sq.q_tno.BCDValue    = buf12[1];
            sq.q_index.BCDValue  = buf12[2];
            sq.min.BCDValue      = buf12[3];
            sq.sec.BCDValue      = buf12[4];
            sq.frame.BCDValue    = buf12[5];
            sq.zero              = buf12[6];
            sq.ap_min.BCDValue   = buf12[7];
            sq.ap_sec.BCDValue   = buf12[8];
            sq.ap_frame.BCDValue = buf12[9];

            //CRC is stored inverted and big endian.. so... do the opposite
            byte hibyte = (byte)(~buf12[10]);
            byte lobyte = (byte)(~buf12[11]);

            sq.q_crc = (ushort)((hibyte << 8) | lobyte);
        }
Beispiel #2
0
        void RunMednaDisc()
        {
            var disc = new Disc();

            OUT_Disc = disc;

            //create a MednaDisc and give it to the disc for ownership
            var md = new MednaDisc(IN_FromPath);

            disc.DisposableResources.Add(md);

            //"length of disc" for bizhawk's purposes (NOT a robust concept!) is determined by beginning of leadout track
            var m_leadoutTrack = md.TOCTracks[100];
            int nSectors       = (int)m_leadoutTrack.lba;

            //make synth param memos
            disc.SynthParams.MednaDisc = md;

            //this is the sole sector synthesizer we'll need
            var synth = new SS_MednaDisc();

            OUT_Disc.SynthProvider = new SimpleSectorSynthProvider()
            {
                SS = synth
            };

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

            //mednafen delivers us what is essentially but not exactly (or completely) a TOCRaw.
            //we need to synth RawTOCEntries from this and then turn it into a proper TOCRaw
            //when coming from mednafen, there are 101 entries.
            //entry[0] is placeholder junk, not to be used
            //entry[100] is the leadout track (A0)
            //A1 and A2 are in the form of FirstRecordedTrackNumber and LastRecordedTrackNumber
            for (int i = 1; i < 101; i++)
            {
                var m_te = md.TOCTracks[i];

                //dont add invalid (absent) items
                if (!m_te.Valid)
                {
                    continue;
                }

                var m_ts = new Timestamp((int)m_te.lba + 150); //these are supposed to be absolute timestamps

                var q = new SubchannelQ
                {
                    q_status = SubchannelQ.ComputeStatus(kADR, (EControlQ)m_te.control),
                    q_tno    = BCD2.FromDecimal(0), //unknown with mednadisc
                    q_index  = BCD2.FromDecimal(i),
                    min      = BCD2.FromDecimal(0), //unknown with mednadisc
                    sec      = BCD2.FromDecimal(0), //unknown with mednadisc
                    frame    = BCD2.FromDecimal(0), //unknown with mednadisc
                    zero     = 0,                   //unknown with mednadisc
                    ap_min   = BCD2.FromDecimal(m_ts.MIN),
                    ap_sec   = BCD2.FromDecimal(m_ts.SEC),
                    ap_frame = BCD2.FromDecimal(m_ts.FRAC),
                    q_crc    = 0 //meaningless
                };

                //a special fixup: mednafen's entry 100 is the lead-out track, so change it into the A2 raw toc entry
                if (i == 100)
                {
                    q.q_index.BCDValue = 0xA2;
                }

                disc.RawTOCEntries.Add(new RawTOCEntry {
                    QData = q
                });
            }

            //synth A0 and A1 entries (indicating first and last recorded tracks and also session type)
            var qA0 = new SubchannelQ
            {
                q_status = SubchannelQ.ComputeStatus(kADR, kUnknownControl),
                q_tno    = BCD2.FromDecimal(0), //unknown with mednadisc
                q_index  = BCD2.FromBCD(0xA0),
                min      = BCD2.FromDecimal(0), //unknown with mednadisc
                sec      = BCD2.FromDecimal(0), //unknown with mednadisc
                frame    = BCD2.FromDecimal(0), //unknown with mednadisc
                zero     = 0,                   //unknown with mednadisc
                ap_min   = BCD2.FromDecimal(md.TOC.first_track),
                ap_sec   = BCD2.FromDecimal(md.TOC.disc_type),
                ap_frame = BCD2.FromDecimal(0),
                q_crc    = 0, //meaningless
            };

            disc.RawTOCEntries.Add(new RawTOCEntry {
                QData = qA0
            });
            var qA1 = new SubchannelQ
            {
                q_status = SubchannelQ.ComputeStatus(kADR, kUnknownControl),
                q_tno    = BCD2.FromDecimal(0), //unknown with mednadisc
                q_index  = BCD2.FromBCD(0xA1),
                min      = BCD2.FromDecimal(0), //unknown with mednadisc
                sec      = BCD2.FromDecimal(0), //unknown with mednadisc
                frame    = BCD2.FromDecimal(0), //unknown with mednadisc
                zero     = 0,                   //unknown with mednadisc
                ap_min   = BCD2.FromDecimal(md.TOC.last_track),
                ap_sec   = BCD2.FromDecimal(0),
                ap_frame = BCD2.FromDecimal(0),
                q_crc    = 0, //meaningless
            };

            disc.RawTOCEntries.Add(new RawTOCEntry {
                QData = qA1
            });
        }