Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
            }
        }