summaryrefslogtreecommitdiff
path: root/Q1.core
diff options
context:
space:
mode:
authorMelodi <62381002+Melodi17@users.noreply.github.com>2026-03-18 06:50:43 +1000
committerMelodi <62381002+Melodi17@users.noreply.github.com>2026-03-18 06:50:43 +1000
commit08ee9a129c81cc1cafcfe830b02b4f9c036334ca (patch)
tree6e4dcbeff96bbbbe65deff7312b416cd50ae69bf /Q1.core
parentc528862deca86c606cead1c9d199ff22a6b4ac89 (diff)
add: Initial implementation of all instructions
Diffstat (limited to 'Q1.core')
-rw-r--r--Q1.core/Arch/Chip.cs9
-rw-r--r--Q1.core/Arch/ChipLayout.cs8
-rw-r--r--Q1.core/Arch/InstructionSet.cs194
3 files changed, 205 insertions, 6 deletions
diff --git a/Q1.core/Arch/Chip.cs b/Q1.core/Arch/Chip.cs
index af131dd..69a0877 100644
--- a/Q1.core/Arch/Chip.cs
+++ b/Q1.core/Arch/Chip.cs
@@ -140,4 +140,13 @@ public class Chip
else throw new InvalidOperationException($"Invalid register index: {index}");
}
+ public void Interrupt(u16 code)
+ {
+ if (code >= ChipLayout.IVT_COUNT)
+ throw new InvalidOperationException($"Invalid interrupt code: {code}");
+
+ this.Push(this.Pc);
+ u16 interruptVectorAddress = (u16) (ChipLayout.IVT_START + code * 2);
+ this.Pc = this.Bus.ReadWord(interruptVectorAddress);
+ }
} \ No newline at end of file
diff --git a/Q1.core/Arch/ChipLayout.cs b/Q1.core/Arch/ChipLayout.cs
index 2948f9a..6c7187b 100644
--- a/Q1.core/Arch/ChipLayout.cs
+++ b/Q1.core/Arch/ChipLayout.cs
@@ -6,10 +6,12 @@ public static class ChipLayout
public const u16 MEMORY_SIZE = 0x4000; // 16KB of memory (0x0000 to 0x3FFF)
public const u16 IVT_START = ChipLayout.MEMORY_START;
- public const u16 IVT_SIZE = 256; // 256 bytes for 128 interrupt vectors (2 bytes each)
+ public const u16 IVT_COUNT = 128; // 128 interrupt vectors
+ public const u16 IVT_SIZE = ChipLayout.IVT_COUNT * 2; // Each vector is 2 bytes (u16)
public const u16 STACK_START = ChipLayout.IVT_START + ChipLayout.IVT_SIZE;
- public const u16 STACK_SIZE = 256 * 2; // 256 words (512 bytes)
+ public const u16 STACK_COUNT = 256;
+ public const u16 STACK_SIZE = ChipLayout.STACK_COUNT * 2; // Each stack entry is 2 bytes (u16)
- public const u16 PROGRAM_START = ChipLayout.MEMORY_START + ChipLayout.STACK_SIZE;
+ public const u16 PROGRAM_START = ChipLayout.STACK_START + ChipLayout.STACK_SIZE;
} \ No newline at end of file
diff --git a/Q1.core/Arch/InstructionSet.cs b/Q1.core/Arch/InstructionSet.cs
index f9c20f8..212e77e 100644
--- a/Q1.core/Arch/InstructionSet.cs
+++ b/Q1.core/Arch/InstructionSet.cs
@@ -12,7 +12,7 @@ public static class InstructionSet
#region Control Group
- InstructionSet.Lookup[0x00] = new InstructionGroup
+ InstructionSet.Lookup[0x00] = new InstructionGroup
{
Implicit = nop,
SimpleAddressing = new SimpleInstruction { Name = "JMP", Execute = InstructionSet.Jump },
@@ -51,6 +51,14 @@ public static class InstructionSet
ExtendedImplicit = nop,
ExtendedAddressing = nopExtended
};
+
+ InstructionSet.Lookup[0x05] = new InstructionGroup
+ {
+ Implicit = nop,
+ SimpleAddressing = new SimpleInstruction { Name = "INT", Execute = InstructionSet.Interrupt },
+ ExtendedImplicit = nop,
+ ExtendedAddressing = nopExtended
+ };
#endregion
@@ -93,7 +101,79 @@ public static class InstructionSet
Implicit = new ImplicitInstruction { Name = "SHPR(DX)", Execute = InstructionSet.ShiftPlaceRightDx },
SimpleAddressing = new SimpleInstruction { Name = "SHPR", Execute = InstructionSet.ShiftPlaceRight },
ExtendedImplicit = nop,
- ExtendedAddressing = new ExtendedInstruction { Name = "SHL", Execute = InstructionSet.ShiftRight }
+ ExtendedAddressing = new ExtendedInstruction { Name = "SHR", Execute = InstructionSet.ShiftRight }
+ };
+
+ #endregion
+
+ #region Logic Group
+
+ InstructionSet.Lookup[0x20] = new InstructionGroup
+ {
+ Implicit = new ImplicitInstruction { Name = "NOT(LX)", Execute = InstructionSet.NotLx },
+ SimpleAddressing = new SimpleInstruction { Name = "NOT", Execute = InstructionSet.Not },
+ ExtendedImplicit = nop,
+ ExtendedAddressing = new ExtendedInstruction { Name = "CMP", Execute = InstructionSet.Compare }
+ };
+
+ InstructionSet.Lookup[0x21] = new InstructionGroup
+ {
+ Implicit = nop,
+ SimpleAddressing = nopSimple,
+ ExtendedImplicit = nop,
+ ExtendedAddressing = new ExtendedInstruction { Name = "LT", Execute = InstructionSet.LessThan }
+ };
+
+ InstructionSet.Lookup[0x22] = new InstructionGroup
+ {
+ Implicit = nop,
+ SimpleAddressing = nopSimple,
+ ExtendedImplicit = nop,
+ ExtendedAddressing = new ExtendedInstruction { Name = "GT", Execute = InstructionSet.GreaterThan }
+ };
+
+ #endregion
+
+ #region Arithmatic Group
+
+ InstructionSet.Lookup[0x30] = new InstructionGroup
+ {
+ Implicit = new ImplicitInstruction { Name = "INC(AX)", Execute = InstructionSet.IncrementAx },
+ SimpleAddressing = new SimpleInstruction { Name = "INC", Execute = InstructionSet.Increment },
+ ExtendedImplicit = nop,
+ ExtendedAddressing = new ExtendedInstruction { Name = "ADD", Execute = InstructionSet.Add }
+ };
+
+ InstructionSet.Lookup[0x31] = new InstructionGroup
+ {
+ Implicit = new ImplicitInstruction { Name = "DEC(AX)", Execute = InstructionSet.DecrementAx },
+ SimpleAddressing = new SimpleInstruction { Name = "DEC", Execute = InstructionSet.Decrement },
+ ExtendedImplicit = nop,
+ ExtendedAddressing = new ExtendedInstruction { Name = "SUB", Execute = InstructionSet.Subtract }
+ };
+
+ InstructionSet.Lookup[0x32] = new InstructionGroup
+ {
+ Implicit = nop,
+ SimpleAddressing = nopSimple,
+ ExtendedImplicit = nop,
+ ExtendedAddressing = new ExtendedInstruction { Name = "DIV", Execute = InstructionSet.Divide }
+ };
+
+ InstructionSet.Lookup[0x33] = new InstructionGroup
+ {
+ Implicit = nop,
+ SimpleAddressing = nopSimple,
+ ExtendedImplicit = nop,
+ ExtendedAddressing = new ExtendedInstruction { Name = "MUL", Execute = InstructionSet.Multiply }
+ };
+
+ InstructionSet.Lookup[0x34] = new InstructionGroup
+ {
+ Implicit = nop,
+ SimpleAddressing = nopSimple,
+ ExtendedImplicit = nop,
+ ExtendedAddressing = new ExtendedInstruction { Name = "DIV", Execute = InstructionSet.Modulo }
};
#endregion
@@ -115,6 +195,13 @@ public static class InstructionSet
throw new NotImplementedException("SUS instruction is not implemented yet.");
}
+ private static void Interrupt(Chip chip, u8 m1, bool word)
+ {
+ u16 interruptNumber = chip.Load(m1, word);
+
+ chip.Interrupt(interruptNumber);
+ }
+
private static void Move(Chip chip, u8 m1, u8 m2, bool word)
{
u16 value = chip.Load(m1, word);
@@ -267,14 +354,115 @@ public static class InstructionSet
#endregion
#region Logic Instructions
-
+ private static void Not(Chip chip, u8 m1, bool word)
+ {
+ u16 value = chip.Load(m1, word);
+ chip.Lx = value == 0 ? (u16)1 : (u16)0;
+ }
+
+ private static void NotLx(Chip chip, bool word)
+ {
+ chip.Lx = chip.Lx == 0 ? (u16)1 : (u16)0;
+ }
+
+ private static void Compare(Chip chip, u8 m1, u8 m2, bool word)
+ {
+ u16 value1 = chip.Load(m1, word);
+ u16 value2 = chip.Load(m2, word);
+ chip.Lx = value1 == value2 ? (u16)1 : (u16)0;
+ }
+
+ private static void LessThan(Chip chip, u8 m1, u8 m2, bool word)
+ {
+ u16 value1 = chip.Load(m1, word);
+ u16 value2 = chip.Load(m2, word);
+ chip.Lx = value1 < value2 ? (u16)1 : (u16)0;
+ }
+
+ private static void GreaterThan(Chip chip, u8 m1, u8 m2, bool word)
+ {
+ u16 value1 = chip.Load(m1, word);
+ u16 value2 = chip.Load(m2, word);
+ chip.Lx = value1 > value2 ? (u16)1 : (u16)0;
+ }
#endregion
#region Arithmetic Instructions
+ private static void Increment(Chip chip, u8 m1, bool word)
+ {
+ u16 value = chip.Load(m1, word);
+ value++;
+ chip.Store(m1, value, word);
+ }
+
+ private static void IncrementAx(Chip chip, bool word)
+ {
+ chip.Ax++;
+ }
+
+ private static void Decrement(Chip chip, u8 m1, bool word)
+ {
+ u16 value = chip.Load(m1, word);
+ value--;
+ chip.Store(m1, value, word);
+ }
+
+ private static void DecrementAx(Chip chip, bool word)
+ {
+ chip.Ax--;
+ }
+
+ private static void Add(Chip chip, u8 m1, u8 m2, bool word)
+ {
+ u16 value1 = chip.Load(m1, word);
+ u16 value2 = chip.Load(m2, word);
+ u16 result = (u16)(value1 + value2);
+
+ chip.Ax = result;
+ }
+
+ private static void Subtract(Chip chip, u8 m1, u8 m2, bool word)
+ {
+ u16 value1 = chip.Load(m1, word);
+ u16 value2 = chip.Load(m2, word);
+ u16 result = (u16)(value1 - value2);
+
+ chip.Ax = result;
+ }
+ private static void Multiply(Chip chip, u8 m1, u8 m2, bool word)
+ {
+ u16 value1 = chip.Load(m1, word);
+ u16 value2 = chip.Load(m2, word);
+ u16 result = (u16)(value1 * value2);
+
+ chip.Ax = result;
+ }
+
+ private static void Divide(Chip chip, u8 m1, u8 m2, bool word)
+ {
+ u16 value1 = chip.Load(m1, word);
+ u16 value2 = chip.Load(m2, word);
+ if (value2 == 0)
+ throw new DivideByZeroException("Attempted to divide by zero.");
+
+ u16 result = (u16)(value1 / value2);
+ chip.Ax = result;
+ }
+
+ private static void Modulo(Chip chip, u8 m1, u8 m2, bool word)
+ {
+ u16 value1 = chip.Load(m1, word);
+ u16 value2 = chip.Load(m2, word);
+ if (value2 == 0)
+ throw new DivideByZeroException("Attempted to modulo by zero.");
+
+ u16 result = (u16)(value1 % value2);
+ chip.Ax = result;
+ }
#endregion
} \ No newline at end of file