public static MemoryBlock ReadStream(Stream stream, int length) { MemoryBlock memoryBlock; // Initialize variables memoryBlock = null; try { // Create the memory block once the file has been successfully opened memoryBlock = new MemoryBlock((int)length); // Read the file using the extension method defined below stream.Read(memoryBlock, 0, memoryBlock.Length); } catch { // Dispose the memory if needed if (memoryBlock != null) memoryBlock.Dispose(); throw; } finally { // Close the file stream.Close(); } return memoryBlock; }
/// <summary>Initializes a new instance of the <see cref="GameBoyMemoryBus"/> class, preloaded with an external ROM.</summary> /// <param name="externalRom">The external ROM to load.</param> public GameBoyMemoryBus(MemoryBlock externalRom) { try { Initialize(); LoadRom(externalRom); } catch { Dispose(); } }
public unsafe VideoStatusSnapshot(GameBoyMemoryBus bus) { this.bus = bus; this.videoMemoryBlock = new MemoryBlock(bus.VideoRam.Length); this.VideoMemory = (byte*)this.videoMemoryBlock.Pointer; this.objectAttributeMemoryBlock = new MemoryBlock(0xA0); // Do not allocate more bytes than needed… GameBoyMemoryBus allocates 0x100 because of the segmented memory. this.ObjectAttributeMemory = (byte*)this.objectAttributeMemoryBlock.Pointer; this.paletteMemoryBlock = new MemoryBlock(bus.PaletteMemory.Length); this.PaletteMemory = (byte*)this.paletteMemoryBlock.Pointer; }
public CodeMap(MemoryBlock rom) { if (rom == null) throw new ArgumentNullException("rom"); if (rom.Length < 32768) // Refuse to analyze a ROM smaller than 32 KB throw new InvalidOperationException(); this.rom = rom; labelDictionary = new Dictionary<int, Label>(); instructionList = new List<Instruction>(); analyzeThread = new Thread(Analyze); asyncResult = new AsyncResult(); }
private void LoadRom(string fileName) { FileInfo fileInfo = new FileInfo(fileName); // Open only existing rom files if (!fileInfo.Exists) throw new FileNotFoundException(); // Limit the rom size to 4 Mb if (fileInfo.Length > 4 * 1024 * 1024) throw new FileTooLongException(); rom = MemoryUtility.ReadFile(fileInfo); memory = new FlexibleGameBoyMemory(rom); disassemblyView.Memory = memory; codeMap = new CodeMap(rom); }
partial void InitializeMemory() { // Use a RNG for uninitialized RAM simulation random = new Random(); unsafe { segmentWriteHandlerArray = new MemoryWriteHandler[256]; segmentMemoryBlock = new MemoryBlock(256 * sizeof(byte*)); // Allocate a memory segment table (256 segments) segmentArray = (byte**)segmentMemoryBlock.Pointer; externalRamBlock = new MemoryBlock(131072); // 128Kb maximum videoMemoryBlock = new MemoryBlock(16384); // 8Kb banks (only in CGB mode) videoMemory = (byte*)videoMemoryBlock.Pointer; workMemoryBlock = new MemoryBlock(32768); // 4Kb banks (switchable in CGB mode) workMemory = (byte*)workMemoryBlock.Pointer; objectAttributeMemoryBlock = new MemoryBlock(256); // 256 bytes of OAM objectAttributeMemory = (byte*)objectAttributeMemoryBlock.Pointer; portMemoryBlock = new MemoryBlock(256); // 256 bytes of High RAM portMemory = (byte*)portMemoryBlock.Pointer; paletteMemoryBlock = new MemoryBlock(16 * 4 * sizeof(ushort)); // 128 bytes of palette ram (only for CGB) paletteMemory = (byte*)paletteMemoryBlock.Pointer; generalMemoryBlock = new MemoryBlock(512); // 256 bytes of register memory and 256 bytes of 'trash' memory externalPortMemory = (byte*)generalMemoryBlock.Pointer; trashMemory = (byte*)generalMemoryBlock.Pointer + 256; dmgBootMemoryBlock = new MemoryBlock(0x100); dmgBootMemory = (byte*)dmgBootMemoryBlock.Pointer; sgbBootMemoryBlock = new MemoryBlock(0x100); sgbBootMemory = (byte*)sgbBootMemoryBlock.Pointer; cgbBootMemoryBlock = new MemoryBlock(0x800); cgbBootMemory = (byte*)cgbBootMemoryBlock.Pointer; } ResetSegments(); ResetWriteHandlers(); }
public static unsafe int Read(this Stream stream, MemoryBlock memoryBlock, int offset, int length) { byte* pMemory; int bytesRead, bytesToRead, totalBytesRead; byte[] buffer; if (memoryBlock == null) throw new ArgumentNullException(); if (offset >= memoryBlock.Length && length != 0) throw new ArgumentOutOfRangeException("offset"); if (length < 0 || offset + length > memoryBlock.Length) throw new ArgumentOutOfRangeException("length"); // Get a pointer to the memory block pMemory = (byte*)memoryBlock.Pointer + offset; // Obtain a reference to the buffer (lazy allocation) buffer = Buffer; totalBytesRead = 0; bytesToRead = Math.Min(bufferLength, length); // Read the file in chunks fixed (byte* pBuffer = buffer) { while ((bytesRead = stream.Read(buffer, 0, bytesToRead)) > 0) { MemoryBlock.Copy(pMemory, pBuffer, bytesRead); totalBytesRead += bytesRead; pMemory += bytesRead; length -= bytesRead; if (length < bytesToRead) bytesToRead = length; } } return totalBytesRead; }
public static void Set(MemoryBlock destination, int destinationOffset, byte value, int length) { if (destination.memoryPointer == null) throw new InvalidOperationException(); if (destinationOffset < 0) throw new ArgumentOutOfRangeException("destinationOffset"); if (length < 0) throw new ArgumentOutOfRangeException("length"); Memory.Set((byte*)destination.memoryPointer + destinationOffset, value, (uint)length); }
public static void Copy(MemoryBlock destination, int destinationOffset, MemoryBlock source, int sourceOffset, int length) { if (destination.memoryPointer == null || source.memoryPointer == null) throw new InvalidOperationException(); if (destinationOffset < 0) throw new ArgumentOutOfRangeException("destinationOffset"); if (sourceOffset < 0) throw new ArgumentOutOfRangeException("sourceOffset"); if (length < 0) throw new ArgumentOutOfRangeException("length"); Memory.Copy((byte*)destination.memoryPointer + destinationOffset, (byte*)source.memoryPointer + sourceOffset, length); }
public FlexibleGameBoyMemory(MemoryBlock externalRom) { this.externalRom = externalRom; this.externalRomBank = 1; }
public unsafe AudioStatusSnapshot(GameBoyMemoryBus bus) { this.bus = bus; this.wavePatternMemoryBlock = new MemoryBlock(16); this.WavePatternMemory = (byte*)this.wavePatternMemoryBlock.Pointer; }
public static unsafe void Write(this BinaryWriter writer, MemoryBlock memoryBlock, int offset, int length) { byte* pMemory; int bytesLeft, bytesToWrite; byte[] buffer; if (memoryBlock == null) throw new ArgumentNullException("memoryBlock"); if (offset >= memoryBlock.Length && length != 0) throw new ArgumentOutOfRangeException("offset"); if (length < 0 || offset + length > memoryBlock.Length) throw new ArgumentOutOfRangeException("length"); // Initialize variables bytesLeft = length; bytesToWrite = bufferLength; // Get a pointer to the memory block pMemory = (byte*)memoryBlock.Pointer + offset; // Obtain a reference to the buffer (lazy allocation) buffer = Buffer; // Write the file in chunks fixed (byte* pBuffer = buffer) { while (bytesLeft > 0) { if (bytesLeft < bytesToWrite) bytesToWrite = bytesLeft; Memory.Copy(pBuffer, pMemory, (uint)bytesToWrite); writer.Write(buffer, 0, bytesToWrite); pMemory += bytesToWrite; bytesLeft -= bytesToWrite; } } }
public static unsafe void WriteFile(FileInfo fileInfo, MemoryBlock memoryBlock) { FileStream fileStream; if (fileInfo == null) throw new ArgumentNullException("fileInfo"); if (memoryBlock == null) throw new ArgumentNullException("memoryBlock"); // Open the file in exclusive mode using (fileStream = fileInfo.Open(FileMode.Open, FileAccess.Write, FileShare.Read)) fileStream.Write(memoryBlock, 0, memoryBlock.Length); }
partial void ResetMemory() { // Reallocate the RAM block if the Mapper request more memory than currently allocated if (mapper != null && mapper.RamSize > externalRamBlock.Length) { externalRamBlock.Dispose(); externalRamBlock = new MemoryBlock(mapper.RamSize); } // Fill various RAM areas with random data at “boot” time // This allows for erasing the previous game residual information. unsafe { // Fill the video RAM. RandomFill(videoMemory, videoMemoryBlock.Length); // Fill the OAM. RandomFill(objectAttributeMemory, objectAttributeMemoryBlock.Length); // Fill the “trash” memory. (Invalid memory) RandomFill(trashMemory, 256); } videoRamBank = 0; workRamBank = 1; internalRomMapped = false; ResetSegments(); ResetWriteHandlers(); }
public void LoadRom(MemoryBlock externalRom) { RomInformation romInformation; if (externalRom == null) throw new ArgumentNullException("externalRom"); if ((externalRom.Length & 0x3FFF) != 0 || (externalRom.Length >> 14) > 256) throw new InvalidOperationException(); romInformation = new RomInformation(externalRom); if (romInformation.RomSize != externalRom.Length) throw new InvalidOperationException(); Mapper mapper; switch (romInformation.RomType) { case RomType.RomOnly: case RomType.RomRam: case RomType.RomRamBattery: mapper = new Mappers.RomController(this); break; case RomType.RomMbc1: case RomType.RomMbc1Ram: case RomType.RomMbc1RamBattery: mapper = new Mappers.MemoryBankController1(this); break; case RomType.RomMbc2: case RomType.RomMbc2Battery: mapper = new Mappers.MemoryBankController2(this); break; case RomType.RomMbc3: case RomType.RomMbc3Ram: case RomType.RomMbc3RamBattery: case RomType.RomMbc3TimerBattery: case RomType.RomMbc3TimerRamBattery: mapper = new Mappers.MemoryBankController3(this); break; case RomType.RomMbc5: case RomType.RomMbc5Ram: case RomType.RomMbc5RamBattery: case RomType.RomMbc5Rumble: case RomType.RomMbc5RumbleRam: case RomType.RomMbc5RumbleRamBattery: mapper = new Mappers.MemoryBankController5(this); break; default: throw new NotSupportedException("Unsupported Cartidge Type"); } #if WITH_THREADING SuspendEmulation(); #endif this.romInformation = romInformation; this.externalRomBlock = externalRom; this.mapper = mapper; this.colorMode = ColorHardware & romInformation.ColorGameBoySupport; #if WITH_DEBUGGING ClearBreakpoints(); #endif Reset(); // Will call “ResumeEmulation”… // Fills the external RAM with random data. // It can be loaded with real data later. unsafe { RandomFill((byte*)externalRamBlock.Pointer, externalRamBlock.Length); } romLoaded = true; }
public void LoadRom(MemoryBlock rom) { emulationStatus = EmulationStatus.Stopped; bus.LoadRom(rom); emulationStatus = EmulationStatus.Paused; OnRomChanged(EventArgs.Empty); }