Beispiel #1
0
        /// <summary>
        /// Sets the PIC execution mode per the XINST device configuration bit value (if present in the memory image).
        /// If no XINST bit can be found in the image or for this processor, the PIC execution mode is left to the user's choice.
        /// </summary>
        private void SetPICExecMode()
        {
            PICExecMode pexec = architecture.Options.PICExecutionMode;

            var dcf = PICMemoryDescriptor.GetDCRField("XINST");

            if (dcf != null)
            {
                var dcr = PICMemoryDescriptor.GetDCR(dcf.RegAddress);
                if (program.SegmentMap.TryFindSegment(dcr.Address, out ImageSegment xinstsegt))
                {
                    uint xinstval;
                    if (dcr.BitWidth <= 8)
                    {
                        xinstval = xinstsegt.MemoryArea.ReadByte(dcf.RegAddress);
                    }
                    else if (dcr.BitWidth <= 16)
                    {
                        xinstval = xinstsegt.MemoryArea.ReadLeUInt16(dcf.RegAddress);
                    }
                    else
                    {
                        xinstval = xinstsegt.MemoryArea.ReadLeUInt32(dcf.RegAddress);
                    }
                    pexec = (dcr.CheckIf("XINST", "ON", xinstval) ? PICExecMode.Extended : PICExecMode.Traditional);
                }
            }
            else
            {
                pexec = PICExecMode.Traditional;
            }
            PICMemoryDescriptor.ExecMode          = pexec;
            architecture.Options.PICExecutionMode = pexec;
            architecture.Description = architecture.Options.ProcessorModel.PICName + $" ({pexec})";
        }
Beispiel #2
0
        protected override void DoRender(MachineInstructionRenderer renderer, MachineInstructionRendererOptions options)
        {
            var memop = Operands[0] as PICOperandBankedMemory ?? throw new InvalidOperationException($"Invalid memory operand: {Operands[0]}");

            renderer.WriteMnemonic(Mnemonic.ToString());
            renderer.Tab();

            var bankmem = PICMemoryDescriptor.CreateBankedAddr(memop);

            if (PICRegisters.TryGetAlwaysAccessibleRegister(bankmem, out var reg))
            {
                renderer.WriteString($"{reg.Name}");
            }
            else
            {
                Operands[0].Render(renderer, options);
            }
        }
Beispiel #3
0
        public override void Render(MachineInstructionWriter writer, MachineInstructionWriterOptions options)
        {
            var memop = op1 as PICOperandBankedMemory ?? throw new InvalidOperationException($"Invalid memory operand: {op1}");

            writer.WriteOpcode(Opcode.ToString());
            writer.Tab();

            var bankmem = PICMemoryDescriptor.CreateBankedAddr(memop);

            if (PICRegisters.TryGetAlwaysAccessibleRegister(bankmem, out var reg))
            {
                writer.WriteString($"{reg.Name}");
            }
            else
            {
                op1.Write(writer, options);
            }
        }
Beispiel #4
0
        private Program PerformValidation()
        {
            var user = program.User;

            user.TextEncoding = Encoding.ASCII;
            bool renameSection = architecture.Options.LoaderType == "raw";

            // Re-assign memory segments according to PIC program memory space definition. Rename segments, as-needed (raw file, segment larger than PIC memory region).

            foreach (var segt in program.SegmentMap.Segments.Values)
            {
                var curAddr = segt.Address;
                var curSize = segt.ContentSize;
                do
                {
                    var regn = PICMemoryDescriptor.GetProgramRegion(curAddr);
                    if (regn == null)
                    {
                        throw new InvalidOperationException("Attempt to load a binary image which is not compatible with the selected PIC's program memory space.");
                    }
                    var fitSize = Math.Min(regn.PhysicalByteAddrRange.End - curAddr, curSize);
                    if (fitSize <= 0)
                    {
                        throw new InvalidOperationException("Attempt to load a binary image which is not compatible with the selected PIC's program memory space.");
                    }
                    var    rd          = segt.MemoryArea.CreateLeReader(curAddr);
                    var    b           = rd.ReadBytes((int)fitSize);
                    var    splitMem    = new MemoryArea(curAddr, b);
                    string segmentName = (renameSection ? GetRegionSequentialName(regn) : GetSegmentSequentialName(segt));
                    var    newsegt     = new ImageSegment(segmentName, splitMem, GetAccessMode(regn));
                    newMap.AddSegment(newsegt);
                    curSize -= (uint)fitSize;
                    curAddr += fitSize;
                } while (curSize > 0);
            }
            program.SegmentMap = newMap;
            SetPICExecMode();
            SetRegistersAtPOR();

            return(program);
        }
Beispiel #5
0
        /// <summary>
        /// Disassemble a single instruction. Return null if the end of the reader has been reached.
        /// </summary>
        /// <returns>
        /// A <seealso cref="PICInstruction"/> instance.
        /// </returns>
        /// <exception cref="AddressCorrelatedException">Thrown when the Address Correlated error
        ///                                              condition occurs.</exception>
        public override PICInstruction DisassembleInstruction()
        {
            IMemoryRegion GetProgRegion()
            {
                if (lastusedregion != null && lastusedregion.Contains(addrCur))
                {
                    return(lastusedregion);
                }
                return(lastusedregion = PICMemoryDescriptor.GetProgramRegion(addrCur));
            }

            if (!rdr.IsValid)
            {
                return(null);
            }
            addrCur = PICProgAddress.Ptr(rdr.Address);
            var regn = GetProgRegion();

            if (regn is null)
            {
                throw new InvalidOperationException($"Unable to retrieve program memory region for address {addrCur.ToString()}.");
            }
            if ((addrCur.Offset % (regn.Trait?.LocSize ?? 1)) != 0)
            {
                instrCur = new PICInstructionNoOpnd(Mnemonic.unaligned)
                {
                    Address = addrCur,
                    Length  = 1
                };
                rdr.Offset += 1; // Consume only the first byte of the binary instruction.
                return(instrCur);
            }

            switch (regn.SubtypeOfMemory)
            {
            case PICMemorySubDomain.Code:
            case PICMemorySubDomain.ExtCode:
            case PICMemorySubDomain.Debugger:
                if (!rdr.TryReadUInt16(out ushort uInstr))
                {
                    return(null);
                }
                return(DecodePICInstruction(uInstr, PICProgAddress.Ptr(rdr.Address)));

            case PICMemorySubDomain.EEData:
                return(DecodeEEPROMInstruction());

            case PICMemorySubDomain.UserID:
                return(DecodeUserIDInstruction());

            case PICMemorySubDomain.DeviceConfig:
                return(DecodeConfigInstruction());

            case PICMemorySubDomain.DeviceID:
                return(DecodeDWInstruction());

            case PICMemorySubDomain.DeviceConfigInfo:      //TODO: Decode DCI
                return(DecodeDCIInstruction());

            case PICMemorySubDomain.DeviceInfoAry:         //TODO: Decode DIA
                return(DecodeDIAInstruction());

            case PICMemorySubDomain.RevisionID:            //TODO: Decode Revision ID
                return(DecodeRevisionIDInstruction());

            case PICMemorySubDomain.Test:
            case PICMemorySubDomain.Other:
            default:
                throw new NotImplementedException($"Disassembly of '{regn.SubtypeOfMemory}' memory region is not yet implemented.");
            }
        }
Beispiel #6
0
        protected override void DoRender(MachineInstructionRenderer renderer, MachineInstructionRendererOptions options)
        {
            var s = PICMemoryDescriptor.RenderDeviceConfigRegister(addr, Values[0]);

            renderer.WriteString(s);
        }
Beispiel #7
0
        public override void Write(MachineInstructionWriter writer, MachineInstructionWriterOptions options)
        {
            var s = PICMemoryDescriptor.RenderDeviceConfigRegister(addr, Values[0]);

            writer.WriteString(s);
        }