Esempio n. 1
0
        public Loader Fixup()
        {
            ushort labelAddress;

            foreach (var reference in _labelReferences)
            {
                if (_labels.TryResolve(reference.Value.Label, out labelAddress))
                {
                    var descriptor = reference.Value;

                    if (descriptor.Relative)
                    {
                        short relAddress = (short)(descriptor.Select(labelAddress - reference.Key - 1));
                        _addressMap.Write(reference.Key, (byte)relAddress);
                    }
                    else if (descriptor.OneByte)
                    {
                        var addressToUse = descriptor.Select(labelAddress + reference.Value.Offset);

                        if (addressToUse >= 0 && addressToUse < 0x100)
                        {
                            _addressMap.Write(reference.Key, (byte)addressToUse);
                        }
                        else
                        {
                            _logger.LogError($"FIXUP ERROR at ${reference.Key:X4} - label '{reference.Value.Label}' at ${addressToUse:X4} is not a single byte");
                            HasErrors = true;
                        }
                    }
                    else
                    {
                        var offsetAddress = descriptor.Select(labelAddress + reference.Value.Offset);

                        if (offsetAddress >= 0 && offsetAddress < 0x10000)
                        {
                            _addressMap.WriteWord(reference.Key, (ushort)offsetAddress);
                        }
                        else
                        {
                            _logger.LogError($"FIXUP ERROR at ${reference.Key:X4} - label '{reference.Value.Label}' at ${offsetAddress:X8} is not valid");
                            HasErrors = true;
                        }
                    }
                }
                else
                {
                    _logger.LogError($"Error: 0x{reference.Key:X4} Label '{reference.Value} is not defined");
                    HasErrors = true;
                }
            }

            _fixupRequired = false;

            if (HasErrors)
            {
                throw new InvalidProgramException("There were errors in the loader");
            }

            return(this);
        }