Skip to content

Commit

Permalink
initial changes to remove OnesCompliment class use ushort as main dat…
Browse files Browse the repository at this point in the history
…a type throughout emulator
  • Loading branch information
jnosek committed Jul 13, 2020
1 parent a243cb0 commit 9da0a8d
Show file tree
Hide file tree
Showing 17 changed files with 102 additions and 231 deletions.
7 changes: 4 additions & 3 deletions AGC/Instructions/Augment.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Apollo.Virtual.AGC.Math;
using System.Xml.Schema;

namespace Apollo.Virtual.AGC.Instructions
{
Expand Down Expand Up @@ -30,14 +31,14 @@ void IInstruction.Execute(ushort K)
var value = cpu.Memory[K];

// if negative
if(value.IsNegative)
if(OnesCompliment.IsNegative(value))
{
cpu.Memory[K] = value + OnesCompliment.NegativeOne;
cpu.Memory[K] = OnesCompliment.AddNegativeOne(value);
}
// if positive
else
{
cpu.Memory[K] = value + OnesCompliment.PositiveOne;
cpu.Memory[K] = OnesCompliment.AddPositiveOne(value);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion AGC/Instructions/BranchZeroOrMinusToFixed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void IInstruction.Execute(ushort K)

// if +0 or negative, jump
if (value == 0 || (value & 0x8000) > 0)
cpu.Z.Write(new OnesCompliment(K));
cpu.Z.Write(K);
}
}
}
6 changes: 3 additions & 3 deletions AGC/Math/DoublePrecision.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
/// </summary>
public class DoublePrecision
{
public OnesCompliment MostSignificantWord { get; protected set; }
public OnesCompliment LeastSignificantWord { get; protected set; }
public ushort MostSignificantWord { get; }
public ushort LeastSignificantWord { get; }

public DoublePrecision(OnesCompliment most, OnesCompliment least)
public DoublePrecision(ushort most, ushort least)
{
MostSignificantWord = most;
LeastSignificantWord = least;
Expand Down
196 changes: 29 additions & 167 deletions AGC/Math/OnesCompliment.cs
Original file line number Diff line number Diff line change
@@ -1,204 +1,66 @@
using System.Diagnostics;
using System;

namespace Apollo.Virtual.AGC.Math
{
/// <summary>
/// This is the base numeric system used by the computer
/// (it does not use Twos-Compliment like x86 computers, so a conversion layer is needed)
/// (it does not use Twos-Compliment like x86 computers, so conversion methods are needed)
/// </summary>
[DebuggerDisplay("{NativeValue}")]
public struct OnesCompliment
public static class OnesCompliment
{
public static readonly OnesCompliment NegativeZero = new OnesCompliment(0xFFFF);
public static readonly OnesCompliment PositiveZero = new OnesCompliment(0x0000);
public static readonly OnesCompliment PositiveOne = new OnesCompliment(0x0001);
public static readonly OnesCompliment NegativeOne = new OnesCompliment(0xFFFE);
public const ushort NegativeZero = 0xFFFF;
public const ushort PositiveZero = 0x0000;
public const ushort PositiveOne = 0x0001;
public const ushort NegativeOne = 0xFFFE;

public ushort NativeValue { get; private set; }
public static bool IsNegativeZero(ushort value) => value == NegativeZero;

public OnesCompliment(ushort value)
{
NativeValue = value;
}

public OnesCompliment(int value)
{
NativeValue = (ushort)value;
}

public bool IsNegativeZero {
get
{
return NativeValue == NegativeZero.NativeValue;
}
}

public bool IsPositiveZero
{
get
{
return NativeValue == 0;
}
}

public bool IsNegative
{
get
{
return (NativeValue & 0x8000) > 0;
}
}

public bool IsPositive
{
get
{
return (NativeValue & 0x8000) == 0;
}
}

public bool IsPositiveOverflow
{
get
{
return (NativeValue & 0xC000) == 0x4000;
}
}

public bool IsNegativeOverflow
{
get
{
return (NativeValue & 0xC000) == 0x8000;
}
}


public static int operator &(OnesCompliment left, ushort right)
{
return left.NativeValue & right;
}

public static int operator |(OnesCompliment left, ushort right)
{
return left.NativeValue | right;
}
public static bool IsPositiveZero(ushort value) => value == 0;

public static OnesCompliment operator ~(OnesCompliment right)
{
return new OnesCompliment(~right.NativeValue);
}
public static bool IsNegative(ushort value) => (value & 0x8000) > 0;

//public static OnesCompliment operator +(OnesCompliment left, ushort right)
//{
// return left + new OnesCompliment(right);
//}

public static OnesCompliment operator +(OnesCompliment left, OnesCompliment right)
public static bool IsPositive(ushort value) => (value & 0x8000) == 0;

public static bool IsPositiveOverflow(ushort value) => (value & 0xC000) == 0x4000;

public static bool IsNegativeOverflow(ushort value) => (value & 0xC000) == 0x8000;

public static ushort Add(ushort left, ushort right)
{
var sum = left.NativeValue + right.NativeValue;
var sum = left + right;

// if we have overflow, most likely from subtracting negative numbers
if ((sum & 0x10000) > 0)
{
// we need to ones compliment correct the negative number by adding 1 and taking the lower 16 bits
// this process is called "end around carry"
sum = sum + 1;
sum = sum & 0xFFFF;
}

return new OnesCompliment(sum);
}

public static bool operator ==(OnesCompliment left, OnesCompliment right)
{
return left.NativeValue == right.NativeValue;
}

public static bool operator !=(OnesCompliment left, OnesCompliment right)
{
return left.NativeValue != right.NativeValue;
}

public static bool operator ==(OnesCompliment left, int right)
{
return left.NativeValue == (ushort)right;
}

public static bool operator !=(OnesCompliment left, int right)
{
return left.NativeValue != (ushort)right;
}

public override bool Equals(object obj)
{
if (obj is OnesCompliment)
{
var toCompare = (OnesCompliment)obj;
return NativeValue == toCompare.NativeValue;
}
else if (obj is ushort)
{
var toCompare = (ushort)obj;
return NativeValue == toCompare;
}
else
{
return base.Equals(obj);
sum += 1;
sum &= 0xFFFF;
}
}

public override int GetHashCode()
{
return NativeValue.GetHashCode();
return (ushort)sum;
}

/// <summary>
/// Automatically return ushort value for OnesCompliment value
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
//public static implicit operator ushort(OnesCompliment a)
//{
// return a.RawValue;
//}
public static ushort AddPositiveOne(ushort value) => Add(value, PositiveOne);

/// <summary>
/// Automatically return onescompliment object from ushort value
/// </summary>
/// <param name="a"></param>
//public static implicit operator OnesCompliment(ushort a)
//{
// return new OnesCompliment(a);
//}
public static ushort AddNegativeOne(ushort value) => Add(value, NegativeOne);

/// <summary>
/// The diminished absolute value is defined as DABS(x)=|x|-1 if |x|>1, or +0 otherwise
/// </summary>
public OnesCompliment GetDiminishedAbsoluteValue()
public static ushort GetDiminishedAbsoluteValue(ushort value)
{
// if negative, NOT 1's to get ABS
ushort absNative = IsNegative ? (ushort)~NativeValue : NativeValue;
ushort abs = IsNegative(value) ? (ushort)~value : value;

var abs = new OnesCompliment(absNative);

if (abs.IsPositive && abs != PositiveZero)
return abs + NegativeOne;
if (IsPositive(abs) && abs != PositiveZero)
return AddNegativeOne(abs);
else
return PositiveZero;
}
}

public static class OnesComplimentHelpers
{
public static OnesCompliment ToOnesCompliment(this int v)
{
return new OnesCompliment(v);
}
public static ushort Convert(short value) => throw new NotImplementedException();

public static OnesCompliment ToOnesCompliment(this ushort v)
{
return new OnesCompliment(v);
}
public static ushort Convert(int value) => throw new NotImplementedException();
}
}
5 changes: 3 additions & 2 deletions AGC/Memory/FixedMemory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Apollo.Virtual.AGC.Math;
using System.Diagnostics;

namespace Apollo.Virtual.AGC.Memory
{
Expand All @@ -16,9 +17,9 @@ public FixedMemory(ushort address, MemoryBank bank)
/// cannot write to fixed memory
/// </summary>
/// <param name="value"></param>
public override void Write(OnesCompliment value)
public override void Write(ushort value)
{
//throw new InvalidOperationException("Cannot write to a fixed memory location");
Debug.Fail("Cannot write to a fixed memory location");
}
}
}
2 changes: 1 addition & 1 deletion AGC/Memory/IMemoryBus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Apollo.Virtual.AGC.Memory
{
public interface IMemoryBus
{
OnesCompliment this[ushort a] { get; set; }
ushort this[ushort a] { get; set; }
int MaxAddress { get; }

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions AGC/Memory/IWord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Apollo.Virtual.AGC.Memory
{
public interface IWord
{
void Write(OnesCompliment value);
OnesCompliment Read();
void Write(ushort value);
ushort Read();
}
}
Loading

0 comments on commit 9da0a8d

Please sign in to comment.