diff options
| author | Melodi <62381002+Melodi17@users.noreply.github.com> | 2026-03-18 06:50:43 +1000 |
|---|---|---|
| committer | Melodi <62381002+Melodi17@users.noreply.github.com> | 2026-03-18 06:50:43 +1000 |
| commit | 08ee9a129c81cc1cafcfe830b02b4f9c036334ca (patch) | |
| tree | 6e4dcbeff96bbbbe65deff7312b416cd50ae69bf /Q1.core/Arch | |
| parent | c528862deca86c606cead1c9d199ff22a6b4ac89 (diff) | |
add: Initial implementation of all instructions
Diffstat (limited to 'Q1.core/Arch')
| -rw-r--r-- | Q1.core/Arch/Chip.cs | 9 | ||||
| -rw-r--r-- | Q1.core/Arch/ChipLayout.cs | 8 | ||||
| -rw-r--r-- | Q1.core/Arch/InstructionSet.cs | 194 |
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 |
