예제 #1
0
 private byte[] ReadSectorCached(int lba)
 {
     //read it if we dont have it cached
     //we wont be caching very much here, it's no big deal
     //identification is not something we want to take a long time
     byte[] data;
     if (!_sectorCache.TryGetValue(lba, out data))
     {
         data = new byte[2048];
         _dsr.ReadLBA_2048(lba, data, 0);
         _sectorCache[lba] = data;
     }
     return(data);
 }
예제 #2
0
        private bool StringAt(string s, int n, int lba = 0)
        {
            //read it if we dont have it cached
            //we wont be caching very much here, it's no big deal
            //identification is not something we want to take a long time
            byte[] data;
            if (!sectorCache.TryGetValue(lba, out data))
            {
                data = new byte[2048];
                dsr.ReadLBA_2048(lba, data, 0);
                sectorCache[lba] = data;
            }

            byte[] cmp  = System.Text.Encoding.ASCII.GetBytes(s);
            byte[] cmp2 = new byte[cmp.Length];
            Buffer.BlockCopy(data, n, cmp2, 0, cmp.Length);
            return(System.Linq.Enumerable.SequenceEqual(cmp, cmp2));
        }
예제 #3
0
        /// <summary>
        /// Easily extracts a mode1 sector range (suitable for extracting ISO FS data files)
        /// </summary>
        public byte[] Easy_Extract_Mode1(int lba_start, int lba_count, int byteLength = -1)
        {
            int totsize = lba_count * 2048;

            byte[] ret = new byte[totsize];
            var    dsr = new DiscSectorReader(this);

            dsr.Policy.DeterministicClearBuffer = false;
            for (int i = 0; i < lba_count; i++)
            {
                dsr.ReadLBA_2048(lba_start + i, ret, i * 2048);
            }
            if (byteLength != -1 && byteLength != totsize)
            {
                byte[] newret = new byte[byteLength];
                Array.Copy(ret, newret, byteLength);
                return(newret);
            }
            return(ret);
        }
예제 #4
0
        //TODO - I'm not sure everything in here makes sense right now..
        public override int Read(byte[] buffer, int offset, int count)
        {
            long remainInDisc = Length - currPosition;

            if (count > remainInDisc)
            {
                count = (int)Math.Min(remainInDisc, int.MaxValue);
            }

            int remain = count;
            int readed = 0;

            while (remain > 0)
            {
                int lba            = (int)(currPosition / SectorSize);
                int lba_within     = (int)(currPosition % SectorSize);
                int todo           = remain;
                int remains_in_lba = SectorSize - lba_within;
                if (remains_in_lba < todo)
                {
                    todo = remains_in_lba;
                }
                if (cachedSector != lba)
                {
                    dsr.ReadLBA_2048(lba, cachedSectorBuffer, 0);
                    cachedSector = lba;
                }
                Array.Copy(cachedSectorBuffer, lba_within, buffer, offset, todo);
                offset       += todo;
                remain       -= todo;
                currPosition += todo;
                readed       += todo;
            }

            return(readed);
        }
예제 #5
0
        public void Think()
        {
            if (RST)
            {
                ResetDevice();
                return;
            }

            if (DataReadInProgress && pce.Cpu.TotalExecutedCycles > DataReadWaitTimer)
            {
                if (SectorsLeftToRead > 0)
                    pce.DriveLightOn = true;

                if (DataIn.Count == 0)
                {
                    // read in a sector and shove it in the queue
                    DiscSystem.DiscSectorReader dsr = new DiscSectorReader(disc); //TODO - cache reader
                    dsr.ReadLBA_2048(CurrentReadingSector, DataIn.GetBuffer(), 0);
                    DataIn.SignalBufferFilled(2048);
                    CurrentReadingSector++;
                    SectorsLeftToRead--;

                    pce.IntDataTransferReady = true;

                    // If more sectors, should set the next think-clock to however long it takes to read 1 sector
                    // but I dont. I dont think transfers actually happen sector by sector
                    // like this, they probably become available as the bits come off the disc.
                    // but lets get some basic functionality before we go crazy.
                    //  Idunno, maybe they do come in a sector at a time.

                    //note to vecna: maybe not at the sector level, but at a level > 1 sample and <= 1 sector, samples come out in blocks
                    //due to the way they are jumbled up (seriously, like put into a blender) for error correction purposes.
                    //we may as well assume that the cd audio decoding magic works at the level of one sector, but it isnt one sample.

                    if (SectorsLeftToRead == 0)
                    {
                        DataReadInProgress = false;
                        DataTransferWasDone = true;
                    }
                    SetPhase(BusPhase_DataIn);
                }
            }

            do
            {
                signalsChanged = false;
                busPhaseChanged = false;

                if (SEL && !BSY)
                {
                    SetPhase(BusPhase_Command);
                }
                else if (ATN && !REQ && !ACK)
                {
                    SetPhase(BusPhase_MessageOut);
                }
                else switch (Phase)
                    {
                        case BusPhase_Command: ThinkCommandPhase(); break;
                        case BusPhase_DataIn: ThinkDataInPhase(); break;
                        case BusPhase_DataOut: ThinkDataOutPhase(); break;
                        case BusPhase_MessageIn: ThinkMessageInPhase(); break;
                        case BusPhase_MessageOut: ThinkMessageOutPhase(); break;
                        case BusPhase_Status: ThinkStatusPhase(); break;
                        default: break;
                    }
            } while (signalsChanged || busPhaseChanged);
        }