/* * Copyright 2019 faddenSoft * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Diagnostics; using Asm65; using TextScanMode = SourceGen.ProjectProperties.AnalysisParameters.TextScanMode; namespace SourceGen { /// /// 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 TWO_BYTE_BRK = "two-byte-brk"; private const string FIRST_WORD_IS_LOAD_ADDR = "first-word-is-load-addr"; private const string DEFAULT_TEXT_ENCODING = "default-text-encoding"; private const string ENTRY_FLAG_EMULATION = "emulation"; private const string ENTRY_FLAG_NATIVE_LONG = "native-long"; private const string ENTRY_FLAG_NATIVE_SHORT = "native-short"; private const string TEXT_ENCODING_C64_PETSCII = "c64-petscii"; /// /// Gets the default load address. /// /// SystemDef instance. /// Specified load address, or 0x1000 if nothing defined. public static int GetLoadAddress(SystemDef sysDef) { Dictionary parms = sysDef.Parameters; int retVal = 0x1000; if (parms.TryGetValue(LOAD_ADDRESS, out string valueStr)) { valueStr = valueStr.Trim(); if (Number.TryParseInt(valueStr, out int parseVal, out int unused)) { retVal = parseVal; } else { Debug.WriteLine("WARNING: bad value for " + LOAD_ADDRESS + ": " + valueStr); } } return retVal; } /// /// Gets the default entry processor status flags. /// /// SystemDef instance. /// Status flags. public static StatusFlags GetEntryFlags(SystemDef sysDef) { Dictionary parms = sysDef.Parameters; StatusFlags retFlags = StatusFlags.AllIndeterminate; // On 65802/65816, this selects emulation mode. On 8-bit CPUs, these have // no effect, but this reflects how the CPU behaves (short regs, emu mode). retFlags.E = retFlags.M = retFlags.X = 1; // Decimal mode is rarely used, and interrupts are generally enabled. Projects // that need to assume otherwise can alter the entry flags. I want to start // with decimal mode clear because it affects the cycle timing display on a // number of 65C02 instructions. retFlags.D = retFlags.I = 0; if (parms.TryGetValue(ENTRY_FLAGS, out string valueStr)) { switch (valueStr) { case ENTRY_FLAG_EMULATION: break; case ENTRY_FLAG_NATIVE_LONG: retFlags.E = retFlags.M = retFlags.X = 0; break; case ENTRY_FLAG_NATIVE_SHORT: retFlags.E = 0; break; default: Debug.WriteLine("WARNING: bad value for " + ENTRY_FLAGS + ": " + valueStr); break; } } return retFlags; } /// /// Gets the default setting for undocumented opcode support. /// /// SystemDef instance. /// Enable/disable value. public static bool GetUndocumentedOpcodes(SystemDef sysDef) { return GetBoolParam(sysDef, UNDOCUMENTED_OPCODES, false); } /// /// Gets the default setting for two-byte BRKs. /// /// SystemDef instance. /// Enable/disable value. public static bool GetTwoByteBrk(SystemDef sysDef) { return GetBoolParam(sysDef, TWO_BYTE_BRK, false); } /// /// Gets the default setting for using the first two bytes of the file as the /// load address. /// /// This is primarily for C64 PRG files. 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. /// /// SystemDef instance. /// True if the first word holds the load address. public static bool GetFirstWordIsLoadAddr(SystemDef sysDef) { return GetBoolParam(sysDef, FIRST_WORD_IS_LOAD_ADDR, false); } /// /// Gets the default setting for the text scan encoding mode. /// /// SystemDef instance. /// Preferred text scan mode. public static TextScanMode GetTextScanMode(SystemDef sysDef) { Dictionary parms = sysDef.Parameters; TextScanMode mode = TextScanMode.LowHighAscii; if (parms.TryGetValue(DEFAULT_TEXT_ENCODING, out string valueStr)) { if (valueStr == TEXT_ENCODING_C64_PETSCII) { mode = TextScanMode.C64Petscii; } } return mode; } /// /// 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 " + paramName + ": " + valueStr); } } return retVal; } } }