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;