示例#1
0
        private static BeImageReader?GetA5InitImageReader(ImageSegment a5dataSegment)
        {
            var a5data = a5dataSegment.MemoryArea;
            var a5dr   = new BeImageReader((ByteMemoryArea)a5data, 0);

            if (!a5dr.TryReadBeUInt32(out uint a5d0))
            {
                return(null);
            }
            if (!a5dr.TryReadBeUInt16(out ushort a5d1))
            {
                return(null);
            }
            var          a5dheaderOffset    = a5dr.ReadBeUInt16();
            const uint   A5Init_Sig_Movem_l = 0x48E77FF8;   // movem.l\td1-d7/a0-a4,-(a7)
            const ushort A5Init_Sig_Lea     = 0x49FA;       // First word of lea\t$????(pc),a4 instruction

            if (a5d0 != A5Init_Sig_Movem_l || a5d1 != A5Init_Sig_Lea || a5dheaderOffset >= a5dataSegment.MemoryArea.Length)
            {
                // Starting code bytes incorrect or
                // Invalid offset to compressed global data - outside of A5World memory segment.
                // No global compressed data
                return(null);
            }
            a5dr.Seek(a5dheaderOffset - 2);
            return(a5dr);
        }
示例#2
0
        private void ProcessJumpTable(uint jtOffset)
        {
            var         j  = new JumpTable();
            ImageReader ir = new BeImageReader(image, jtOffset);

            j.AboveA5Size     = ir.ReadBeUInt32();
            j.BelowA5Size     = ir.ReadBeUInt32();
            j.JumpTableSize   = ir.ReadBeUInt32();
            j.JumpTableOffset = ir.ReadBeUInt32();
            uint size = j.JumpTableSize;

            while (size > 0)
            {
                JumpTableEntry jte = new JumpTableEntry();
                jte.RoutineOffsetFromSegmentStart = ir.ReadBeUInt16();
                jte.Instruction       = ir.ReadBeUInt32();
                jte.LoadSegTrapNumber = ir.ReadBeUInt16();
                Debug.WriteLine(string.Format("Jump table entry: {0:x2} {1:X4} {2:X2}", jte.RoutineOffsetFromSegmentStart, jte.Instruction, jte.LoadSegTrapNumber));
                size -= 8;
            }
        }
示例#3
0
        public void Relocate()
        {
            var  memA5          = (ByteMemoryArea)platform.A5World.MemoryArea;
            var  a5belowWriter  = new BeImageWriter(memA5, 0);
            var  a5belowReader  = new BeImageReader(memA5, 0);
            uint a5globalOffset = platform.A5Offset - a5dbelow;

            var a5WorldAddress = (UInt32)((platform.A5World.Address.Offset + platform.A5Offset) & 0xFFFFFFFF);

            // set Repeat count = 1, reset after each completed copy cycle
            // byte token lower 4 bits number of words to copy from compressed data
            // byte token upper 4 bits number of words to skip in global application data space
            // if either value is 0 then get run length value which is in bytes.
            // if the new run length value for copy is 0 then it's the end of compression data.

            for (;;)
            {
                int a5repeat = 1;
                // Skip is number of 16-bit words to skip
                uint a5globalSkip = a5dr.ReadByte();
                if (a5globalSkip == 0)
                {
                    a5globalSkip = a5dr.ReadByte();
                    if (a5globalSkip == 0)
                    {
                        break;
                    }
                    if (a5globalSkip > 0x7F)
                    {
                        a5globalSkip = ((a5globalSkip & 0x7F) << 8) + a5dr.ReadByte();
                        a5globalSkip = (a5globalSkip << 16) + a5dr.ReadBeUInt16();
                    }
                    else
                    {
                        a5repeat = ResourceFork.GetRunLengthValue(a5dr, ref a5repeat);
                        //$BUG: a5repeat could return the value 0. The do-while below will
                        // decrement a5repeat before testing. This will lead to an effective
                        // repeat count of 2^32; likely not wanted.
                    }
                }
                else
                {
                    if ((a5globalSkip & 0x80) == 0x80)
                    {
                        a5globalSkip = ((a5globalSkip & 0x7F) << 8) + a5dr.ReadByte();
                    }
                }
                a5globalSkip = a5globalSkip * 2;
                do
                {
                    a5globalOffset += a5globalSkip;
                    a5belowReader.Seek(a5globalOffset, SeekOrigin.Begin);
                    uint a5ptrOffset = a5belowReader.ReadBeUInt32();
                    a5belowWriter.Position = (int)a5globalOffset;

                    // write relocated A5World pointers to absolute address in A5World segment
                    // Possible register/mark as Global pointer references to strings

                    a5belowWriter.WriteBeUInt32((a5WorldAddress + a5ptrOffset) & 0xFFFFFFFF);
                    --a5repeat;
                } while (a5repeat > 0);
            }
        }