public void TapeInput(string tapePath) { var z80snap = Z80File.LoadZ80(tapePath); _displayUnit.BorderColor = z80snap.BORDER; _z80.ApplyZ80Snapshot(z80snap); }
private byte[] ExtractZ80(string filename) { Z80_SNAPSHOT z80Snapshot; z80Snapshot = Z80File.LoadZ80(filename); //Array.Copy(z80Snapshot.RAM_BANK[8], 0, _buffer, 0, kLoadingScreenLength); Array.Copy(z80Snapshot.RAM_BANK[10], 0, _buffer, 0, kLoadingScreenLength); return(_buffer); //Debug.Log(z80Snapshot.) //// info from: http://www.worldofspectrum.org/faq/reference/z80format.htm //const int kProgramCounterOffset = 6; //bool z80Version2or3 = sourceFileBytes[kProgramCounterOffset] == 0 && sourceFileBytes[kProgramCounterOffset + 1] == 0; //const int kVersion1HeaderByteLength = 30; //const int kVersion2And3AdditionalHeaderLengthOffset = 30; //int headerLength = kVersion1HeaderByteLength; //if(z80Version2or3) //{ // int additionalHeaderLength = Get16BitWord(sourceFileBytes, kVersion2And3AdditionalHeaderLengthOffset); // headerLength += additionalHeaderLength; //} //int offset = headerLength + 1; // not sure why it's +1 from reading the doc at WoS, but this is correct ////int offset = headerLength; // not sure why it's +1 from reading the doc at WoS, but this is correct //int compressedBlockLength = Get16BitWord(sourceFileBytes, offset); //int blockPageNumber = sourceFileBytes[offset + 2]; //Debug.Log("ExtractZ80 - headerLength == " + headerLength + " compressedBlockLength: " + compressedBlockLength + " blockPageNumber: " + blockPageNumber); //return null; }
private static ushort UnpackMem(ushort offset, byte[] data, int start, int end, bool compressed, Z80File File) { for (int i = start; i < end; ++i) { if (compressed && data[i + 0] == 0x00 && data[i + 1] == 0xED && data[i + 2] == 0xED && data[i + 3] == 0x00) { break; } if (data[i] == 0xED && data[i + 1] == 0xED && compressed) { var repeat = data[i + 2]; var value = data[i + 3]; while (repeat-- > 0) { File.Data[offset++] = value; } i = i + 3; } else { File.Data[offset++] = data[i]; } } return(offset); }
public static unsafe Z80File Load(string FileName) { byte[] data; try { data = File.ReadAllBytes(FileName); } catch { return(null); } Z80File file = new Z80File(); int headerLength = 30; bool compressed = true; fixed(byte *bData = data) { Z80Header *head = (Z80Header *)&bData[0]; if (head->PC == 00) { Z80Header2 *head2 = (Z80Header2 *)&bData[headerLength]; headerLength += head2->Size + 2; head->PC = head2->PC; } compressed = (head->Info1 & 32) != 0; fixed(byte *cData = file.Header) { Z80TransferHeader *th = (Z80TransferHeader *)&cData[0]; th->I = head->I; th->HLP = head->HLP; th->DEP = head->DEP; th->BCP = head->BCP; th->AFP = head->AFP; th->HL = head->HL; th->DE = head->DE; th->BC = head->BC; th->IY = head->IY; th->IX = head->IX; th->IFFStatus = head->IFF1; th->R = (byte)((head->R & 0x7F) | ((head->Info1 & 0x80) << 7)); th->AF = head->AF; th->SP = head->SP; th->IntMode = (byte)(head->Info2 & 3); th->BorderColor = (byte)((head->Info1 >> 1) & 7); th->PC = head->PC; } } if (headerLength != 30) { compressed = true; int i = headerLength; while (i != data.Length) { var datalen = Word(data, i); var page = GetPage(data[i + 2]); if (page == 0xFFFF) { return(null); } i = i + 3; // skip block header if (datalen == 0xFFFF) { datalen = 16384; compressed = false; } UnpackMem(page, data, i, i + datalen, compressed, file); i += datalen; } } else { UnpackMem(0x4000, data, 30, data.Length, compressed, file); } return(file); }
public ZXSerialLoaderResult LoadFile(string SerialPort, string FileName, int BlockSize, Action <int> Progress) { string ext = Path.GetExtension(FileName).ToLower(); SpectrumFile program; switch (ext) { case ".hex": program = HEXFile.Load(FileName); break; case ".sna": program = SNAFile.Load(FileName); break; case ".z80": program = Z80File.Load(FileName); break; case ".tap": program = TAPFile.Load(FileName); break; default: return(ZXSerialLoaderResult.Unsupported); } if (program == null) { return(ZXSerialLoaderResult.FileError); } try { string dvResponse; using (SerialPort serial = new SerialPort(SerialPort, serialSpeed, Parity.None, 8, StopBits.One)) { serial.Open(); serial.ReadTimeout = 5000; serial.WriteTimeout = 5000; serial.Write(program.Operation); if ((dvResponse = serial.ReadLine()) != "RDY") { return(ZXSerialLoaderResult.UnknownResponse); } if (program.Header != null) { serial.Write(program.Header, 0, program.Header.Length); } int pos = program.StartAddress; bool finished = false; double passPercent = BlockSize * 100 / (program.EndAddress - program.StartAddress); double currentPercent = 0; while (pos < program.EndAddress) { int segLen = Math.Min(BlockSize, program.EndAddress - pos); byte[] tmpBuffer = new byte[2]; if (pos + segLen >= program.EndAddress) //Is last segment? { finished = true; tmpBuffer[0] = 1; } serial.Write(tmpBuffer, 0, 1); //Send last segment tmpBuffer[0] = (byte)(pos & 0xFF); tmpBuffer[1] = (byte)((pos >> 8) & 0xFF); serial.Write(tmpBuffer, 0, 2); //Send segment address tmpBuffer[0] = (byte)(segLen & 0xFF); tmpBuffer[1] = (byte)((segLen >> 8) & 0xFF); serial.Write(tmpBuffer, 0, 2); //Send segment size if ((dvResponse = serial.ReadLine()) != "OK") { return(ZXSerialLoaderResult.UnknownResponse); } //Send segment serial.Write(program.Data, pos, segLen); //Wait for acknowledge if (!finished) { if ((dvResponse = serial.ReadLine()) != "NEXT") { return(ZXSerialLoaderResult.UnknownResponse); } } currentPercent += passPercent; if (Progress != null) { Progress((int)Math.Min(100, currentPercent)); } pos += segLen; } if (Progress != null) { Progress(1000); } Console.WriteLine(serial.ReadLine()); if (Progress != null) { Progress(2000); } Console.WriteLine(serial.ReadLine()); if (Progress != null) { Progress(3000); } serial.Close(); return(ZXSerialLoaderResult.Success); } } catch { return(ZXSerialLoaderResult.SerialPortError); } }
public void LoadZ80(string path) { var z80 = new Z80File(path); z80.Load(this); }