diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs index b32b77d..2f463e8 100644 --- a/SourceGen/DisasmProject.cs +++ b/SourceGen/DisasmProject.cs @@ -227,7 +227,8 @@ namespace SourceGen { mDataFileName = dataFileName; FileDataCrc32 = CommonUtil.CRC32.OnWholeBuffer(0, mFileData); - // Mark the first byte as code so we have something to do. + // Mark the first byte as code so we have something to do. This may get + // overridden later. TypeHints[0] = CodeAnalysis.TypeHint.Code; } @@ -241,9 +242,6 @@ namespace SourceGen { bool includeUndoc = Setup.SystemDefaults.GetUndocumentedOpcodes(sysDef); CpuDef tmpDef = CpuDef.GetBestMatch(cpuType, includeUndoc); - int loadAddr = Setup.SystemDefaults.GetLoadAddress(sysDef); - mAddrMap.Set(0, loadAddr); - // Store the best-matched CPU in properties, rather than whichever was originally // requested. This way the behavior of the project is the same for everyone, even // if somebody has a newer app version with specialized handling for the @@ -254,6 +252,23 @@ namespace SourceGen { ProjectProps.EntryFlags = Setup.SystemDefaults.GetEntryFlags(sysDef); + // Configure the load address. + int loadAddr; + if (Setup.SystemDefaults.GetFirstWordIsLoadAddr(sysDef) && mFileData.Length > 2) { + loadAddr = RawData.GetWord(mFileData, 0, 2, false); + loadAddr -= 2; + if (loadAddr < 0) { + loadAddr += 65536; + } + OperandFormats[0] = FormatDescriptor.Create(2, FormatDescriptor.Type.NumericLE, + FormatDescriptor.SubType.None); + TypeHints[0] = CodeAnalysis.TypeHint.NoHint; + TypeHints[2] = CodeAnalysis.TypeHint.Code; + } else { + loadAddr = Setup.SystemDefaults.GetLoadAddress(sysDef); + } + mAddrMap.Set(0, loadAddr); + foreach (string str in sysDef.SymbolFiles) { ProjectProps.PlatformSymbolFileIdentifiers.Add(str); } diff --git a/SourceGen/RuntimeData/SystemDefs.json b/SourceGen/RuntimeData/SystemDefs.json index ac0b622..954f594 100644 --- a/SourceGen/RuntimeData/SystemDefs.json +++ b/SourceGen/RuntimeData/SystemDefs.json @@ -173,6 +173,7 @@ "ExtensionScripts" : [ ], "Parameters" : { + "first-word-is-load-addr":"true" } }, { diff --git a/SourceGen/Setup/SystemDefaults.cs b/SourceGen/Setup/SystemDefaults.cs index 23b4970..2601a33 100644 --- a/SourceGen/Setup/SystemDefaults.cs +++ b/SourceGen/Setup/SystemDefaults.cs @@ -20,10 +20,14 @@ using System.Diagnostics; using Asm65; namespace SourceGen.Setup { - public class SystemDefaults { + /// + /// Helper functions for extracting values from a SystemDef instance. + /// + public static class SystemDefaults { private const string LOAD_ADDRESS = "load-address"; private const string ENTRY_FLAGS = "entry-flags"; private const string UNDOCUMENTED_OPCODES = "undocumented-opcodes"; + private const string FIRST_WORD_IS_LOAD_ADDR = "first-word-is-load-addr"; private const string ENTRY_FLAG_EMULATION = "emulation"; private const string ENTRY_FLAG_NATIVE_LONG = "native-long"; @@ -34,7 +38,7 @@ namespace SourceGen.Setup { /// Gets the default load address. /// /// SystemDef instance. - /// Load address. + /// Specified load address, or 0x1000 if nothing defined. public static int GetLoadAddress(SystemDef sysDef) { Dictionary parms = sysDef.Parameters; int retVal = 0x1000; @@ -94,15 +98,40 @@ namespace SourceGen.Setup { /// SystemDef instance. /// Enable/disable value. public static bool GetUndocumentedOpcodes(SystemDef sysDef) { - Dictionary parms = sysDef.Parameters; - bool retVal = false; + return GetBoolParam(sysDef, UNDOCUMENTED_OPCODES, false); + } - if (parms.TryGetValue(UNDOCUMENTED_OPCODES, out string valueStr)) { + /// + /// Gets the default setting for using the first two bytes of the file as the + /// load address. + /// + /// This is primarily for C64. Apple II DOS 3.3 binary files also put the load + /// address first, followed by the length, but that's typically stripped out when + /// the file is extracted. + /// + /// + /// + public static bool GetFirstWordIsLoadAddr(SystemDef sysDef) { + return GetBoolParam(sysDef, FIRST_WORD_IS_LOAD_ADDR, false); + } + + /// + /// Looks for a parameter with a matching name and a boolean value. + /// + /// SystemDef reference. + /// Name of parameter to look for. + /// Default value. + /// Parsed value, or defVal if the parameter doesn't exist or the value is not + /// a boolean string. + private static bool GetBoolParam(SystemDef sysDef, string paramName, bool defVal) { + Dictionary parms = sysDef.Parameters; + bool retVal = defVal; + + if (parms.TryGetValue(paramName, out string valueStr)) { if (bool.TryParse(valueStr, out bool parseVal)) { retVal = parseVal; } else { - Debug.WriteLine("WARNING: bad value for " + UNDOCUMENTED_OPCODES + - ": " + valueStr); + Debug.WriteLine("WARNING: bad value for " + paramName + ": " + valueStr); } } return retVal;