public static void LoadProgramFile(string in_file_name, TVCMemory in_memory) { ProgramStorage storage = new ProgramStorage(); string extension = Path.GetExtension(in_file_name); if (string.Compare(extension, ".zip", true) == 0) { using (ZipArchive archive = ZipFile.Open(in_file_name, ZipArchiveMode.Read)) { foreach (ZipArchiveEntry entry in archive.Entries) { // Load CAS file if (string.Compare(Path.GetExtension(entry.Name), ".cas", true) == 0) { using (Stream file_stream = entry.Open()) { LoadCAS(file_stream, storage); } break; } // Load DSK file if (string.Compare(Path.GetExtension(entry.Name), ".dsk", true) == 0) { using (FileStream file_stream = new FileStream(in_file_name, FileMode.Open, FileAccess.Read, FileShare.Read)) { LoadDSK(file_stream, storage); } break; } } } } else { // Load CAS file if (string.Compare(extension, ".cas", true) == 0) { using (FileStream file_stream = new FileStream(in_file_name, FileMode.Open, FileAccess.Read, FileShare.Read)) { LoadCAS(file_stream, storage); } } // Load DSK file if (string.Compare(extension, ".dsk", true) == 0) { using (FileStream file_stream = new FileStream(in_file_name, FileMode.Open, FileAccess.Read, FileShare.Read)) { LoadDSK(file_stream, storage); } } } // Set memory content in_memory.LoadFromProgramStorage(storage); }
/////////////////////////////////////////////////////////////////////////////// // Initialize CAS Headers public static TVCFileTypes.CASProgramFileHeaderType CreateProgramFileHeader(ProgramStorage in_storage) { TVCFileTypes.CASProgramFileHeaderType header = new TVCFileTypes.CASProgramFileHeaderType(); header.FileType = in_storage.GetFileTypeByte(); header.FileLength = in_storage.Length; header.Autorun = (byte)((in_storage.AutoStart) ? 0xff : 0x00); header.Version = 0; return(header); }
public static void SaveProgramFile(string in_file_name, TVCMemory in_memory) { using (FileStream cas_stream = new FileStream(in_file_name, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096)) { ProgramStorage storage = new ProgramStorage(); // get memory content in_memory.SaveToProgramStorage(storage); SaveCAS(cas_stream, storage); } }
/////////////////////////////////////////////////////////////////////////////// // Saves CAS file public static void CASSave(Stream in_file, ProgramStorage in_storage) { using (BinaryWriter cas_file = new BinaryWriter(in_file)) { TVCFileTypes.CASUPMHeaderType upm_header = CreateUPMHeader(in_storage); TVCFileTypes.CASProgramFileHeaderType program_header = CreateProgramFileHeader(in_storage); cas_file.Write(upm_header); cas_file.Write(program_header); cas_file.Write(in_storage.Data, 0, in_storage.Length); } }
public int ReadFromMemory(int in_pos, ProgramStorage in_storage) { Length = in_storage.Data[in_pos]; in_pos += sizeof(byte); if (Length != BAS_LINEND && Length != BAS_PRGEND) { Number = BitConverter.ToUInt16(in_storage.Data, in_pos); in_pos += sizeof(ushort); } return(in_pos); }
/////////////////////////////////////////////////////////////////////////////// // Initizes UPM header public static TVCFileTypes.CASUPMHeaderType CreateUPMHeader(ProgramStorage in_storage) { TVCFileTypes.CASUPMHeaderType header = new TVCFileTypes.CASUPMHeaderType(); ushort cas_length = (ushort)(in_storage.Length + Marshal.SizeOf(typeof(TVCFileTypes.CASUPMHeaderType)) + Marshal.SizeOf(typeof(TVCFileTypes.CASProgramFileHeaderType))); header.FileType = TVCFileTypes.CASBlockHeaderFileUnbuffered; header.CopyProtect = (byte)((in_storage.CopyProtect) ? 0xff : 0x00); header.BlockNumber = (ushort)(cas_length / 128); header.LastBlockBytes = (byte)(cas_length % 128); return(header); }
public static void SaveProgramFile(string in_file_name, TVCMemory in_memory, BASFile.EncodingType in_encoding) { using (FileStream bas_stream = new FileStream(in_file_name, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096)) { ProgramStorage storage = new ProgramStorage(); // get memory content in_memory.SaveToProgramStorage(storage); BASFile bas_file = new BASFile(); bas_file.Encoding = in_encoding; bas_file.Save(bas_stream, storage); } }
public static void LoadDSK(Stream in_stream, ProgramStorage in_storage) { //Read File as FAT12 Image FatPartition FAT = new FatPartition(in_stream); foreach (FatDirectoryEntry entry in FAT.RootDirectory) { if (string.Compare(entry.Extension, "cas", true) == 0) { byte[] cas_file = FAT.ReadFile(entry, in_stream); using (MemoryStream cas_stream = new MemoryStream(cas_file)) { LoadCAS(cas_stream, in_storage); } break; } } }
/////////////////////////////////////////////////////////////////////////////// // Loads CAS file public static void CASLoad(Stream in_file, ProgramStorage in_storage) { TVCFileTypes.CASUPMHeaderType upm_header = new TVCFileTypes.CASUPMHeaderType(); TVCFileTypes.CASProgramFileHeaderType program_header = new TVCFileTypes.CASProgramFileHeaderType(); // open CAS file using (BinaryReader cas_file = new BinaryReader(in_file)) { // load UPM header cas_file.Read(upm_header); // load program header cas_file.Read(program_header); // Check validity if (!CASCheckHeaderValidity(program_header)) { throw new FileFormatException("Invalid CAS header"); } if (!CASCheckUPMHeaderValidity(upm_header)) { throw new FileFormatException("Invalid UPM header"); } cas_file.Read(in_storage.Data, 0, program_header.FileLength); in_storage.Length = program_header.FileLength; in_storage.CopyProtect = (upm_header.CopyProtect != 0); in_storage.AutoStart = (program_header.Autorun != 0); in_storage.SetFileTypeByte(program_header.FileType); } // generate TVC filename //PCToTVCFilename(g_db_file_name, in_file_name); }
/////////////////////////////////////////////////////////////////////////////// // Saves BAS file public bool Save(Stream in_stream, ProgramStorage in_storage) { Encoding encoding; // set open options based on encoding type switch (Encoding) { case EncodingType.Ansi: encoding = new ASCIIEncoding(); break; case EncodingType.Auto: case EncodingType.Utf8: encoding = new UTF8Encoding(); break; case EncodingType.Unicode: encoding = new UnicodeEncoding(); break; default: encoding = null; break; } using (StreamWriter bas_file = new StreamWriter(in_stream, encoding)) { // start processing of the memory int current_pos = 0; int next_line_pos = 0; int line_data_end; StatusCode state = StatusCode.Tokenizing; BasicLineHeader current_line = new BasicLineHeader(); current_line.ReadFromMemory(current_pos, in_storage); while (current_pos < in_storage.Length && current_line.Length != BAS_PRGEND) { // check basic format if (current_line.Length < BasicLineHeader.Size) { bas_file.Write("\n*** Broken BASIC program\n"); break; } // set next line pointer next_line_pos = current_pos + current_line.Length; // write line number bas_file.Write("{0,4:d} ", current_line.Number); // decode line current_pos += BasicLineHeader.Size; line_data_end = next_line_pos; if (current_pos <= line_data_end - 1 && in_storage.Data[line_data_end - 1] == BAS_LINEND) { line_data_end--; } state = StatusCode.Tokenizing; while (current_pos < line_data_end) { char current_char = (char)in_storage.Data[current_pos]; // decode token or character if (state == StatusCode.Tokenizing) { // store tokenized item if (Encoding == EncodingType.Ansi) { bas_file.Write(m_ansi_tokenized_map[current_char]); } else { bas_file.Write(m_unicode_tokenized_map[current_char]); } } else { // store non tokenized item if (Encoding == EncodingType.Ansi) { if (current_char < 0x80) { bas_file.Write(m_ansi_tokenized_map[current_char]); } else { bas_file.Write("\\x{0:X2}", current_char); } } else { if (current_char < 0x80) { bas_file.Write(m_unicode_tokenized_map[current_char]); } else { bas_file.Write("\\x{0:X2}", current_char); } } } // update status if (current_char == '"') { state ^= StatusCode.Quotation; } else { if (!state.HasFlag(StatusCode.Quotation)) { if (current_char == BAS_TOKEN_DATA) { state |= StatusCode.Data; } else { if (current_char == BAS_TOKEN_COLON) { state &= ~StatusCode.Data; } else { if (current_char == BAS_TOKEN_COMMENT || current_char == BAS_TOKEN_REM) { state |= StatusCode.Remark; } } } } } current_pos++; } bas_file.WriteLine(); current_pos = next_line_pos; current_line.ReadFromMemory(current_pos, in_storage); } // write remaining data offset int remaining_byte_index = current_pos + 1; // +1 beacuse of the BAS_PRGEND byte if (remaining_byte_index < in_storage.Length) { bas_file.WriteLine("BYTESOFFSET {0}", remaining_byte_index); } // write remaining data int bytes_in_a_line = 0; while (remaining_byte_index < in_storage.Length) { if (bytes_in_a_line == 0) { bas_file.Write("BYTES "); } bas_file.Write("\\x{0:X2}", in_storage.Data[remaining_byte_index]); remaining_byte_index++; bytes_in_a_line++; // write new line if (bytes_in_a_line > MAX_BYTES_IN_A_LINE) { bas_file.WriteLine(); bytes_in_a_line = 0; } } // new line if (bytes_in_a_line > 0) { bas_file.WriteLine(); } // write autostart if (in_storage.AutoStart) { bas_file.WriteLine("AUTOSTART"); } } return(true); }
public static void SaveCAS(Stream in_stream, ProgramStorage in_storage) { CASFile.CASSave(in_stream, in_storage); }
public static void LoadCAS(Stream in_stream, ProgramStorage in_storage) { CASFile.CASLoad(in_stream, in_storage); }