private void DisassembleDDCBandFDCBOpcodesCorrectly() { var fakeBus = A.Fake <IBus>(); var ram = HexFileReader.Read("../../../HexFiles/TestDDCBandFDCB.hex"); var expectedDisassembly = new Dictionary <ushort, string> { { 0x8000, "RL (IX+2)" }, { 0x8004, "RL (IY-3)" }, }; A.CallTo(() => fakeBus.Read(A <ushort> ._, A <bool> ._)) .ReturnsLazily((ushort addr, bool ro) => ram[addr]); var cpu = new Z80() { A = 0x00, PC = 0x8000 }; cpu.ConnectToBus(fakeBus); var disassembledCode = cpu.Disassemble(0x8000, 0x8007); Assert.Equal(expectedDisassembly, disassembledCode); }
private void DisassembleMultiplicationHexFileCorrectly() { var fakeBus = A.Fake <IBus>(); var ram = HexFileReader.Read("../../../HexFiles/Multiplication.hex"); var expectedDisassembly = new Dictionary <ushort, string> { { 0x8000, "LD BC,&0015" }, { 0x8003, "LD B,&08" }, { 0x8005, "LD DE,&002A" }, { 0x8008, "LD D,&00" }, { 0x800A, "LD HL,&0000" }, { 0x800D, "SRL C" }, { 0x800F, "JR C,$+3" }, { 0x8011, "ADD HL,DE" }, { 0x8012, "SLA E" }, { 0x8014, "RL D" }, { 0x8016, "DEC B" }, { 0x8017, "JP NZ,&800D" }, }; A.CallTo(() => fakeBus.Read(A <ushort> ._, A <bool> ._)) .ReturnsLazily((ushort addr, bool ro) => ram[addr]); var cpu = new Z80() { A = 0x00, PC = 0x8000 }; cpu.ConnectToBus(fakeBus); var disassembledCode = cpu.Disassemble(0x8000, 0x8017); Assert.Equal(expectedDisassembly, disassembledCode); }
public void HexFileReaderHandlesOffset() { var reader = new HexFileReader(new List <string>() { ":020000040800F2", // offset 0x8000000 ":080000000102030405060708D4", // write 8 bytes (1,2,3,4,5,6,7,8) starting from address 0 ":080010000102030405060708C4", // write 8 bytes (1,2,3,4,5,6,7,8) starting from address 16 ":00000001FF" }, 32, 0x8000000); var memoryBlock = reader.Parse(); for (int i = 0; i < memoryBlock.Cells.Length; i++) { memoryBlock.Cells[i].Address.Should().Be(0x8000000 + i); } memoryBlock.Cells.Take(8).All(cell => cell.Modified).Should().BeTrue(); memoryBlock.Cells.Skip(8).Take(8).All(cell => !cell.Modified).Should().BeTrue(); memoryBlock.Cells.Skip(16).Take(8).All(cell => cell.Modified).Should().BeTrue(); memoryBlock.Cells.Skip(24).Take(8).All(cell => !cell.Modified).Should().BeTrue(); memoryBlock.Cells.Select(cell => cell.Value) .ShouldAllBeEquivalentTo(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 255, 255, 255, 255, 255, 255, 255, 255, 1, 2, 3, 4, 5, 6, 7, 8, 255, 255, 255, 255, 255, 255, 255, 255, }); }
private void DisassembleArithmetic1HexFileCorrectly() { var fakeBus = A.Fake <IBus>(); var expectedDisassembly = new Dictionary <ushort, string> { { 0x0080, "LD A,&05" }, { 0x0082, "LD B,&0A" }, { 0x0084, "ADD A,B" }, { 0x0085, "ADD A,A" }, { 0x0086, "LD C,&0F" }, { 0x0088, "SUB A,C" }, { 0x0089, "LD H,&08" }, { 0x008B, "LD L,&FF" }, { 0x008D, "LD (HL),A" }, { 0x008E, "NOP" }, }; var ram = HexFileReader.Read("../../../HexFiles/Arithmetic1.hex"); A.CallTo(() => fakeBus.Read(A <ushort> ._, A <bool> ._)) .ReturnsLazily((ushort addr, bool ro) => ram[addr]); var cpu = new Z80() { A = 0x00, PC = 0x0080 }; cpu.ConnectToBus(fakeBus); var disassembledCode = cpu.Disassemble(0x0080, 0x008E); Assert.Equal(expectedDisassembly, disassembledCode); }
private void Download_Click(object sender, RoutedEventArgs e) { var path = Path.Text; byte[] binary = new Byte[1024]; HidStream hidStream = device.Open(); if (!string.IsNullOrEmpty(path)) { if (!File.Exists(path)) { lbl_status.Text = "配列文件不存在"; return; } if (path.EndsWith("bin", StringComparison.CurrentCultureIgnoreCase)) { using (var stream = File.Open(path, FileMode.Open)) { stream.Read(binary, 0, 1024); } } else { HexFileReader reader = new HexFileReader(path, 1024); MemoryBlock memoryRepresentation = reader.Parse(); int index = 0; foreach (var item in memoryRepresentation.Cells) { binary[index++] = item.Value; if (index == 1024) { break; } } } // 第一个Byte为0x55代表启用此Keymap binary[0] = 0x55; } try { byte[] packet = new byte[60]; for (int i = 0; i < (binary.Length / 60); i++) { Array.Copy(binary, i * 60, packet, 0, 60); SendPacket(hidStream, (uint)i, packet); } } catch (Exception exp) { lbl_status.Text = exp.Message; } lbl_status.Text = "完成"; }
public void HexFileReaderHexFileLoad() { HexFileReader reader = new HexFileReader(@"c:\xx.hex"); MemoryBlock block = reader.Parse(); byte[] cells = block.Cells.Select(c => c.Value).ToArray(); string data = BitConverter.ToString(cells).Replace('-', ' '); Console.Write(data); }
private static MemoryBlock ReadHexFile(IEnumerable <string> hexFileContents, int memorySize) { try { var reader = new HexFileReader(hexFileContents, memorySize); return(reader.Parse()); } catch (Exception ex) { Logger?.Error(ex.Message, ex); throw; } }
public void FillProgramMemory(string filename) { HexFileReader reader = new HexFileReader(filename, ProgramMemory.Length * 2); var mem = reader.Parse(); for (int hexIndex = 0, memIndex = 0; hexIndex < ProgramMemory.Length * 2; hexIndex += 2, memIndex++) { UInt16 value = (UInt16)((mem.Cells[hexIndex].Value) | mem.Cells[hexIndex + 1].Value << 8); ProgramMemory[memIndex] = value; } }
private static MemoryBlock ReadHexFile(IEnumerable <string> hexFileContents, int memorySize) { try { var reader = new HexFileReader(hexFileContents, memorySize); return(reader.Parse()); } catch (Exception ex) { UploaderLogger.LogErrorAndThrow(ex.Message); } return(null); }
public IAsyncAction Program(String fileName, int memorySize) { Debug.WriteLine("Load hex file"); HexFileReader reader = new HexFileReader(fileName, memorySize); Debug.WriteLine("Load hex file: Done"); Debug.WriteLine("Parse hex file: Start"); MemoryBlock memoryRepresentation = reader.Parse(); Debug.WriteLine("Parse hex file: Done"); return(ProgramInternal(memoryRepresentation).AsAsyncAction()); }
private void ExecuteArithmeticTestRoutine1Successfully() { var fakeBus = A.Fake <IBus>(); //` Arithmetic Test Routine #1 - 10 instructions //` Filename: Arithmetic1.hex //` //` 0080 .ORG 0080h //` //` 0080 3E 05 LD A,05h //` 0082 06 0A LD B,0Ah //` 0084 80 ADD A,B //` 0085 87 ADD A,A //` 0086 0E 0F LD C,0Fh //` 0088 91 SUB C //` 0089 26 08 LD H,08h //` 008B 2E FF LD L,0FFh //` 008D 77 LD (HL),A //` 008E 00 NOP var ram = HexFileReader.Read("../../../HexFiles/Arithmetic1.hex"); A.CallTo(() => fakeBus.Read(A <ushort> ._, A <bool> ._)) .ReturnsLazily((ushort addr, bool ro) => ram[addr]); A.CallTo(() => fakeBus.Write(A <ushort> ._, A <byte> ._)) .Invokes((ushort addr, byte data) => UpdateMemory(addr, data)); var cpu = new Z80() { A = 0x00, B = 0x00, C = 0x00, H = 0x00, L = 0x00, PC = 0x0080 }; cpu.ConnectToBus(fakeBus); // Run 10 instructions for (int i = 0; i < 10; i++) { cpu.Step(); Debug.WriteLine($"A = {cpu.A} B = {cpu.B} C = {cpu.C} H = {cpu.H} L = {cpu.L}"); } Assert.Equal(0x0F, ram[0x08FF]); void UpdateMemory(ushort addr, byte data) { ram[addr] = data; } }
private void ReadSimpleHexFileWithOnlySingleDataRecord() { var fakeBus = A.Fake <IBus>(); // Routine #1 - 58 T-Cycles // .ORG 0080h // // LD A,05h // LD B,0Ah // ADD A, B // ADD A, A // LD C,0Fh // SUB C // LD H,08h // LD L,0FFh // LD(HL),A // NOP var ram = HexFileReader.Read("../../../HexFiles/Arithmetic1.hex"); A.CallTo(() => fakeBus.Read(A <ushort> ._, A <bool> ._)) .ReturnsLazily((ushort addr, bool ro) => ram[addr]); A.CallTo(() => fakeBus.Write(A <ushort> ._, A <byte> ._)) .Invokes((ushort addr, byte data) => UpdateMemory(addr, data)); var cpu = new Z80() { A = 0x00, B = 0x00, C = 0x00, H = 0x00, L = 0x00, PC = 0x0080 }; cpu.ConnectToBus(fakeBus); for (int i = 0; i < 10; i++) { cpu.Step(); } Assert.Equal(0x0F, ram[0x08FF]); void UpdateMemory(ushort addr, byte data) { ram[addr] = data; } }
private void ExecuteEightBitMultiplicationRoutineSuccessfully() { var fakeBus = A.Fake <IBus>(); //` Arithmetic Test Routine #2 //` Filename: Multiplication.hex //` //` 8000 .ORG 8000h //` //`8000 01 15 00 LD BC,21 //`8003 06 08 LD B,8 //`8005 11 2A 00 LD DE,42 //`8008 16 00 LD D,0 //`800A 21 00 00 LD HL,0 //`800D CB 39 MULTI: SRL C; LSB in Carry Flag //`800F 30 01 JR NC, NOADD //`8011 19 ADD HL, DE //`8012 CB 23 NOADD: SLA E //`8014 CB 12 RL D //`8016 05 DEC B //`8017 C2 0D 80 JP NZ, MULTI var ram = HexFileReader.Read("../../../HexFiles/Multiplication.hex"); A.CallTo(() => fakeBus.Read(A <ushort> ._, A <bool> ._)) .ReturnsLazily((ushort addr, bool ro) => ram[addr]); var cpu = new Z80() { A = 0x00, B = 0x00, C = 0x00, H = 0x00, L = 0x00, PC = 0x8000 }; cpu.ConnectToBus(fakeBus); while (cpu.PC < 0x8020) { cpu.Step(); } Assert.Equal(0x0372, cpu.HL); }
public IEnumerable <AssemblyStatement> Disassemble() { var reader = new HexFileReader(_options.File, 4 * 1024 * 1024); var memoryRepresentation = reader.Parse(); var highestOffset = memoryRepresentation.HighestModifiedOffset; var enumerator = new MemoryCellEnumerator(memoryRepresentation.Cells); while (enumerator.Index < highestOffset) { enumerator.ClearBuffer(); var offset = enumerator.Index; var bytes = enumerator.ReadWord(Endianness.LittleEndian); var opcodes = OpCodeIdentification.IdentifyOpCode(bytes).ToList(); // TODO: make a preference configurable if synonyms exist. // For now, just pick the first item. var opcode = opcodes.Any() ? opcodes.First() : new DATA(); if (opcode.Size == OpCodeSize._32) { var extraBytes = enumerator.ReadWord(Endianness.LittleEndian); bytes = bytes.Concat(extraBytes).ToArray(); } var type = opcode.GetType(); var operands = OperandExtraction.ExtractOperands(type, bytes); var statement = new AssemblyStatement(opcode, operands) { Offset = offset, OriginalBytes = enumerator.Buffer }; yield return(statement); } }
private void OpenFile() { if (Target == Target.unknown) { throw new FormatException("The firmware file format is not supported."); } else { if (Target == Target.stm32) { Bytes = File.ReadAllBytes(FilePath); ProcessDFUFile(); Opened = true; } if (Target == Target.teensy) { try { HexFileReader reader = new HexFileReader(FilePath, ErgodoxMemSize); MemoryBlock memory = reader.Parse(); Bytes = new byte[ErgodoxMemSize]; var i = 0; foreach (MemoryCell cell in memory.Cells) { Bytes[i] = cell.Value; i++; } Opened = true; } catch (Exception e) { throw new FormatException("The firmware file is corrupted.", e); } } } }
public void HexFileReaderHandlesDataRecordType() { var reader = new HexFileReader(new List <string>() { ":080000000102030405060708D4", // write 8 bytes (1,2,3,4,5,6,7,8) starting from address 0 ":080010000102030405060708C4", // write 8 bytes (1,2,3,4,5,6,7,8) starting from address 16 ":00000001FF" }, 32); var memoryBlock = reader.Parse(); memoryBlock.Cells.Take(8).All(cell => cell.Modified).Should().BeTrue(); memoryBlock.Cells.Skip(8).Take(8).All(cell => !cell.Modified).Should().BeTrue(); memoryBlock.Cells.Skip(16).Take(8).All(cell => cell.Modified).Should().BeTrue(); memoryBlock.Cells.Skip(24).Take(8).All(cell => !cell.Modified).Should().BeTrue(); memoryBlock.Cells.Select(cell => cell.Value) .ShouldAllBeEquivalentTo(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 255, 255, 255, 255, 255, 255, 255, 255, 1, 2, 3, 4, 5, 6, 7, 8, 255, 255, 255, 255, 255, 255, 255, 255, }); }
private void DownloadKeymap(string path) { byte[] binary = new Byte[1024]; HidStream hidStream = device.Open(); if (!string.IsNullOrEmpty(path)) { if (!File.Exists(path)) { setStatusText("配列文件不存在"); return; } if (path.EndsWith("bin", StringComparison.CurrentCultureIgnoreCase)) { using (var stream = File.Open(path, FileMode.Open)) { stream.Read(binary, 0, 1024); } } else { HexFileReader reader = new HexFileReader(path, 1024); MemoryBlock memoryRepresentation = reader.Parse(); int index = 0; foreach (var item in memoryRepresentation.Cells) { binary[index++] = item.Value; if (index == 1024) { break; } } } if (!checkSum(binary)) { setStatusText("Keymap校验不通过"); return; } } try { byte[] packet = new byte[60]; var count = binary.Length / 60; for (int i = 0; i < count; i++) { Array.Copy(binary, i * 60, packet, 0, 60); setStatusText($"{i + 1}/{count}"); if (SendPacket(hidStream, (uint)i, packet)) { break; } } setStatusText("下载完毕"); } catch (Exception exp) { setStatusText(exp.Message); } }
private void DownloadKeymap(string path) { byte[] binary = new Byte[1024]; HidStream hidStream = device.Open(); if (!string.IsNullOrEmpty(path)) { if (!File.Exists(path)) { setStatusText("配列文件不存在"); return; } if (path.EndsWith("bin", StringComparison.CurrentCultureIgnoreCase)) { using (var stream = File.Open(path, FileMode.Open)) { stream.Read(binary, 0, 1024); } } else { HexFileReader reader = new HexFileReader(path, 1024); MemoryBlock memoryRepresentation = reader.Parse(); int index = 0; foreach (var item in memoryRepresentation.Cells) { binary[index++] = item.Value; if (index == 1024) { break; } } } if (!checkSum(binary)) { setStatusText("Keymap校验不通过"); return; } } const int keymap_offset = 0x55; try { byte[] packet = new byte[56]; var count = (binary.Length - keymap_offset) / 56; // Keymap for (int i = 0; i < count; i++) { Array.Copy(binary, i * 56 + keymap_offset, packet, 0, 56); setStatusText($"{i + 1}/{count}"); if (SendPacket(hidStream, (uint)i, packet)) { break; } } // Fn for (int i = 0; i < 64; i += 56) { Array.Copy(binary, i + 0x15, packet, 0, i < 64 ? 56 : i - 56); if (SendPacketFn(hidStream, (uint)i / 56, packet)) { break; } } // Write to storage SendCommand(hidStream, 0x3E, new byte[] { 0xFF }); setStatusText("下载完毕"); } catch (Exception exp) { setStatusText(exp.Message); } }
private void Download_Click(object sender, RoutedEventArgs e) { var path = Path.Text; byte[] binary = new Byte[660]; HidStream hidStream = device.Open(); if (!string.IsNullOrEmpty(path)) { if (!File.Exists(path)) { lbl_status.Text = "配列文件不存在"; return; } if (path.EndsWith("bin", StringComparison.CurrentCultureIgnoreCase)) { using (var stream = File.Open(path, FileMode.Open)) { stream.Read(binary, 0, 660); } } else { HexFileReader reader = new HexFileReader(path, 1024); MemoryBlock memoryRepresentation = reader.Parse(); int index = 0; foreach (var item in memoryRepresentation.Cells) { binary[index++] = item.Value; if (index == 660) { break; } } const int checksum_offset = 0x13; const int total_size = checksum_offset + 2 + 0x40 + (14 * 5 * 8); int checksum = (binary[checksum_offset]) + (binary[checksum_offset + 1] << 8); int calc_sum = 0xFEED; for (int i = checksum_offset + 2; i < total_size - 1; i += 2) { var c = (binary[i]) + (binary[i + 1] << 8); calc_sum += c; calc_sum %= 0x10000; } if (checksum != calc_sum) { lbl_status.Text = "Keymap校验不通过"; return; } } } try { byte[] packet = new byte[60]; for (int i = 0; i < (binary.Length / 60); i++) { Array.Copy(binary, i * 60, packet, 0, 60); SendPacket(hidStream, (uint)i, packet); } lbl_status.Text = "完成"; } catch (Exception exp) { lbl_status.Text = exp.Message; } }