mirror of https://github.com/fadden/6502bench.git
119 lines
4.6 KiB
C#
119 lines
4.6 KiB
C#
/*
|
|
* Copyright 2018 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.Diagnostics;
|
|
|
|
namespace Asm65 {
|
|
/// <summary>
|
|
/// Memory address primitives.
|
|
/// </summary>
|
|
public static class Address {
|
|
/// <summary>
|
|
/// Address value to use for non-addressable regions of the file, such as file headers
|
|
/// stripped by the system loader or chunks loaded into non-addressable memory.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// If you change this value, also update the copy in CommonUtil.AddressMap.
|
|
/// </remarks>
|
|
public const int NON_ADDR = -1025;
|
|
|
|
/// <summary>
|
|
/// Human-readable string that represents a non-addressable location.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This is a bit deep to bury a human-readable string, but it's useful to have the
|
|
/// value in one place.
|
|
/// </remarks>
|
|
public const string NON_ADDR_STR = "NA";
|
|
|
|
|
|
/// <summary>
|
|
/// Converts a 16- or 24-bit address to a string.
|
|
/// </summary>
|
|
/// <param name="addr">Address</param>
|
|
/// <param name="always24">If true, force 24-bit output mode.</param>
|
|
/// <returns>Formatted string.</returns>
|
|
public static string AddressToString(int addr, bool always24) {
|
|
if (!always24 && addr < 65536) {
|
|
return addr.ToString("x4");
|
|
} else {
|
|
return (addr >> 16).ToString("x2") + "/" + (addr & 0xffff).ToString("x4");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parses and validates a 16- or 24-bit address, expressed in hexadecimal. Bits
|
|
/// 16-23 may be specified with a slash.
|
|
///
|
|
/// The following all evaluate to the same thing: 1000, $1000, 0x1000, 00/1000.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This doesn't handle "NA", because most of the time we want to parse an actual address.
|
|
/// </remarks>
|
|
/// <param name="addrStr">String to validate.</param>
|
|
/// <param name="max">Maximum valid address value.</param>
|
|
/// <param name="addr">Integer form.</param>
|
|
/// <returns>True if the address is valid.</returns>
|
|
public static bool ParseAddress(string addrStr, int max, out int addr) {
|
|
string trimStr = addrStr.Trim(); // strip whitespace
|
|
if (trimStr.Length < 1) {
|
|
addr = -1;
|
|
return false;
|
|
}
|
|
if (trimStr[0] == '$') {
|
|
trimStr = trimStr.Remove(0, 1);
|
|
}
|
|
|
|
int slashIndex = trimStr.IndexOf('/');
|
|
try {
|
|
if (slashIndex < 0) {
|
|
addr = Convert.ToInt32(trimStr, 16);
|
|
if (addr < 0 || addr > max) {
|
|
Debug.WriteLine("Simple value out of range");
|
|
addr = -1;
|
|
return false;
|
|
}
|
|
} else {
|
|
string[] splitStr = trimStr.Split('/');
|
|
if (splitStr.Length == 2) {
|
|
int addr1 = Convert.ToInt32(splitStr[0], 16);
|
|
int addr2 = Convert.ToInt32(splitStr[1], 16);
|
|
addr = (addr1 << 16) | addr2;
|
|
// Check components separately to catch overflow.
|
|
if (addr1 < 0 || addr1 > 255 || addr2 < 0 || addr2 > 65535 ||
|
|
addr > max) {
|
|
Debug.WriteLine("Slash value out of range");
|
|
addr = -1;
|
|
return false;
|
|
}
|
|
} else {
|
|
addr = -1;
|
|
}
|
|
}
|
|
} catch (Exception) {
|
|
// Thrown from Convert.ToInt32
|
|
//Debug.WriteLine("ValidateAddress: conversion of '" + addrStr + "' failed: " +
|
|
// ex.Message);
|
|
addr = -1;
|
|
return false;
|
|
}
|
|
|
|
//Debug.WriteLine("Conv " + addrStr + " --> " + addr.ToString("x6"));
|
|
return true;
|
|
}
|
|
}
|
|
}
|