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); }
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)); }
/// <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); }
//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); }
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); }