Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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,
            });
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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 = "完成";
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
 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;
     }
 }
Beispiel #8
0
        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());
        }
Beispiel #11
0
        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;
            }
        }
Beispiel #12
0
        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;
            }
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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);
            }
        }
Beispiel #15
0
        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);
                    }
                }
            }
        }
Beispiel #16
0
        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,
            });
        }
Beispiel #17
0
        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);
            }
        }
Beispiel #18
0
        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;
            }
        }