public byte[] GetSZXData() { byte[] szxData = null; using (MemoryStream ms = new MemoryStream(1000)) { using (BinaryWriter r = new BinaryWriter(ms)) { byte[] buf; ZXST_Block block = new ZXST_Block(); buf = ByteUtililty.RawSerialize(header); //header is filled in by the callee machine r.Write(buf); block.Id = GetUIntFromString("CRTR"); block.Size = (uint)Marshal.SizeOf(creator); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(creator); r.Write(buf); block.Id = GetUIntFromString("Z80R"); block.Size = (uint)Marshal.SizeOf(z80Regs); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(z80Regs); r.Write(buf); block.Id = GetUIntFromString("SPCR"); block.Size = (uint)Marshal.SizeOf(specRegs); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(specRegs); r.Write(buf); block.Id = GetUIntFromString("KEYB"); block.Size = (uint)Marshal.SizeOf(keyboard); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(keyboard); r.Write(buf); if (paletteLoaded) { block.Id = GetUIntFromString("PLTT"); block.Size = (uint)Marshal.SizeOf(palette); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(palette); r.Write(buf); } if (header.MachineId > (byte)ZXTYPE.ZXSTMID_48K) { block.Id = GetUIntFromString("AY\0\0"); block.Size = (uint)Marshal.SizeOf(ayState); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(ayState); r.Write(buf); byte[] ram = new byte[16384]; for (int f = 0; f < 8; f++) { ZXST_RAMPage ramPage = new ZXST_RAMPage(); ramPage.chPageNo = (byte)f; ramPage.wFlags = 0; //not compressed block.Id = GetUIntFromString("RAMP"); block.Size = (uint)(Marshal.SizeOf(ramPage) + 16384); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(ramPage); r.Write(buf); for (int g = 0; g < 8192; g++) { ram[g] = (byte)(RAM_BANK[f * 2][g] & 0xff); ram[g + 8192] = (byte)(RAM_BANK[f * 2 + 1][g] & 0xff); } r.Write(ram); } } else //48k { byte[] ram = new byte[16384]; //page 0 ZXST_RAMPage ramPage = new ZXST_RAMPage(); ramPage.chPageNo = 0; ramPage.wFlags = 0; //not compressed block.Id = GetUIntFromString("RAMP"); block.Size = (uint)(Marshal.SizeOf(ramPage) + 16384); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(ramPage); r.Write(buf); for (int g = 0; g < 8192; g++) { //me am angry.. poda thendi... saree vangi tharamattaaai?? poda! nonsense! style moonji..madiyan changu..malayalam ariyatha //Lol! That's my wife cursing me for spending my time on this crap instead of her. Such a sweetie pie! ram[g] = (byte)(RAM_BANK[0][g] & 0xff); ram[g + 8192] = (byte)(RAM_BANK[1][g] & 0xff); } r.Write(ram); //page 2 ramPage.chPageNo = 2; ramPage.wFlags = 0; //not compressed //ramPage.chData = new byte[16384]; // Array.Copy(RAM_BANK[2 * 2], 0, ramPage.chData, 0, 8192); //Array.Copy(RAM_BANK[2 * 2 + 1], 0, ramPage.chData, 8192, 8192); block.Id = GetUIntFromString("RAMP"); block.Size = (uint)(Marshal.SizeOf(ramPage) + 16384); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(ramPage); r.Write(buf); for (int g = 0; g < 8192; g++) { ram[g] = (byte)(RAM_BANK[ramPage.chPageNo * 2][g] & 0xff); ram[g + 8192] = (byte)(RAM_BANK[ramPage.chPageNo * 2 + 1][g] & 0xff); } r.Write(ram); //page 5 ramPage.chPageNo = 5; ramPage.wFlags = 0; //not compressed block.Id = GetUIntFromString("RAMP"); block.Size = (uint)(Marshal.SizeOf(ramPage) + 16384); buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(ramPage); r.Write(buf); for (int g = 0; g < 8192; g++) { ram[g] = (byte)(RAM_BANK[ramPage.chPageNo * 2][g] & 0xff); ram[g + 8192] = (byte)(RAM_BANK[ramPage.chPageNo * 2 + 1][g] & 0xff); } r.Write(ram); } if (InsertTape) { tape = new ZXST_Tape(); block.Id = GetUIntFromString("TAPE"); char[] ext = System.IO.Path.GetExtension(externalTapeFile).ToLower().ToCharArray(); tape.fileExtension = new char[16]; for (int f = 1; f < ext.Length; f++) { tape.fileExtension[f - 1] = ext[f]; } externalTapeFile = externalTapeFile + char.MinValue; //add a null terminator tape.flags = 0; tape.currentBlockNo = 0; tape.compressedSize = externalTapeFile.Length; tape.uncompressedSize = externalTapeFile.Length; block.Size = (uint)Marshal.SizeOf(tape) + (uint)tape.uncompressedSize; buf = ByteUtililty.RawSerialize(block); r.Write(buf); buf = ByteUtililty.RawSerialize(tape); r.Write(buf); char[] tapeName = externalTapeFile.ToCharArray(); r.Write(tapeName); } } szxData = ms.ToArray(); } return(szxData); }
public bool LoadSZX(Stream fs) { for (int f = 0; f < 16; f++) { RAM_BANK[f] = new byte[8192]; } using (BinaryReader r = new BinaryReader(fs)) { int bytesToRead = (int)fs.Length; byte[] buffer = new byte[bytesToRead]; int bytesRead = r.Read(buffer, 0, bytesToRead); if (bytesRead == 0) { return(false); //something bad happened! } GCHandle pinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); //Read in the szx header to begin proceedings header = (ZXST_Header)Marshal.PtrToStructure(pinnedBuffer.AddrOfPinnedObject(), typeof(ZXST_Header)); if (header.MajorVersion != 1) { pinnedBuffer.Free(); return(false); } string formatName = GetID(header.Magic); int bufferCounter = Marshal.SizeOf(header); while (bufferCounter < bytesRead) { //Read the block info ZXST_Block block = (ZXST_Block)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_Block)); bufferCounter += Marshal.SizeOf(block); string blockID = GetID(block.Id); switch (blockID) { case "SPCR": //Read the ZXST_SpecRegs structure specRegs = (ZXST_SpecRegs)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_SpecRegs)); break; case "Z80R": //Read the ZXST_SpecRegs structure z80Regs = (ZXST_Z80Regs)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_Z80Regs)); break; case "KEYB": //Read the ZXST_SpecRegs structure keyboard = (ZXST_Keyboard)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_Keyboard)); break; case "AY\0\0": ayState = (ZXST_AYState)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_AYState)); break; case "+3\0\0": plus3Disk = (ZXST_Plus3Disk)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_Plus3Disk)); numDrivesPresent = plus3Disk.numDrives; plus3DiskFile = new ZXST_DiskFile[plus3Disk.numDrives]; externalDisk = new String[plus3Disk.numDrives]; InsertDisk = new bool[plus3Disk.numDrives]; break; case "DSK\0": ZXST_DiskFile df = (ZXST_DiskFile)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_DiskFile)); plus3DiskFile[df.driveNum] = df; InsertDisk[df.driveNum] = true; int offset2 = bufferCounter + Marshal.SizeOf(df); char[] file = new char[df.uncompressedSize]; Array.Copy(buffer, offset2, file, 0, df.uncompressedSize); //leave out the \0 terminator externalDisk[df.driveNum] = new String(file); break; case "TAPE": tape = (ZXST_Tape)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_Tape)); InsertTape = true; //Embedded tape file if ((tape.flags & 1) != 0) { int offset = bufferCounter + Marshal.SizeOf(tape); //Compressed? if ((tape.flags & 2) != 0) { MemoryStream compressedData = new MemoryStream(buffer, offset, tape.compressedSize); MemoryStream uncompressedData = new MemoryStream(); using (ZInputStream zipStream = new ZInputStream(compressedData)) { byte[] tempBuffer = new byte[2048]; int bytesUnzipped = 0; while ((bytesUnzipped = zipStream.read(tempBuffer, 0, 2048)) > 0) { uncompressedData.Write(tempBuffer, 0, bytesUnzipped); } embeddedTapeData = uncompressedData.ToArray(); compressedData.Close(); uncompressedData.Close(); } } else { embeddedTapeData = new byte[tape.compressedSize]; Array.Copy(buffer, offset, embeddedTapeData, 0, tape.compressedSize); } } else //external tape file { int offset = bufferCounter + Marshal.SizeOf(tape); char[] file2 = new char[tape.compressedSize - 1]; Array.Copy(buffer, offset, file2, 0, tape.compressedSize - 1); //leave out the \0 terminator externalTapeFile = new String(file2); } break; case "RAMP": //Read the ZXST_SpecRegs structure ZXST_RAMPage ramPages = (ZXST_RAMPage)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_RAMPage)); if (ramPages.wFlags == ZXSTRF_COMPRESSED) { int offset = bufferCounter + Marshal.SizeOf(ramPages); int compressedSize = ((int)block.Size - (Marshal.SizeOf(ramPages)));// - Marshal.SizeOf(block) - 1 )); MemoryStream compressedData = new MemoryStream(buffer, offset, compressedSize); MemoryStream uncompressedData = new MemoryStream(); using (ZInputStream zipStream = new ZInputStream(compressedData)) { byte[] tempBuffer = new byte[2048]; int bytesUnzipped = 0; while ((bytesUnzipped = zipStream.read(tempBuffer, 0, 2048)) > 0) { uncompressedData.Write(tempBuffer, 0, bytesUnzipped); } byte[] pageData = uncompressedData.ToArray(); { Array.Copy(pageData, 0, RAM_BANK[ramPages.chPageNo * 2], 0, 8192); Array.Copy(pageData, 0 + 8192, RAM_BANK[ramPages.chPageNo * 2 + 1], 0, 8192); } compressedData.Close(); uncompressedData.Close(); } } else { int bufferOffset = bufferCounter + Marshal.SizeOf(ramPages); { Array.Copy(buffer, bufferOffset, RAM_BANK[ramPages.chPageNo * 2], 0, 8192); Array.Copy(buffer, bufferOffset + 8192, RAM_BANK[ramPages.chPageNo * 2 + 1], 0, 8192); } } break; case "PLTT": palette = (ZXST_PaletteBlock)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(buffer, bufferCounter), typeof(ZXST_PaletteBlock)); paletteLoaded = true; break; default: //unrecognised block, so skip to next break; } bufferCounter += (int)block.Size; //Move to next block } pinnedBuffer.Free(); return(true); } }