Skip to content

Commit

Permalink
Terminal and additional extended base instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
TollyH committed May 1, 2024
1 parent 52e350c commit b9742be
Show file tree
Hide file tree
Showing 5 changed files with 325 additions and 8 deletions.
10 changes: 9 additions & 1 deletion AAPFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ public enum AAPFeatures : ulong
ExtensionFileSystem = 0b10000000,
ExtensionTerminal = 0b100000000,

All = 0b111111111,
All = V1CallStack
| ExtensionSigned
| ExtensionFloat
| ExtensionExtendedBase
| GZipCompressed
| ExtensionExternalAssembly
| ExtensionMemoryAllocation
| ExtensionFileSystem
| ExtensionTerminal,
Incompatible = ~All
}

Expand Down
6 changes: 6 additions & 0 deletions Data.cs
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,12 @@ public static class Data
// TERM_GCX (Get Horizontal Cursor Position)
{ ("TERM_GCX", new OperandType[1] { OperandType.Register }), new Opcode(0x07, 0x31) },

// TERM_GSY (Get Terminal Buffer Height)
{ ("TERM_GSY", new OperandType[1] { OperandType.Register }), new Opcode(0x07, 0x32) },

// TERM_GSX (Get Terminal Buffer Width)
{ ("TERM_GSX", new OperandType[1] { OperandType.Register }), new Opcode(0x07, 0x33) },

// TERM_BEP (Beep)
{ ("TERM_BEP", Array.Empty<OperandType>()), new Opcode(0x07, 0x40) },

Expand Down
209 changes: 202 additions & 7 deletions Processor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class Processor : IDisposable

public readonly bool UseV1CallStack;
public readonly bool MapStack;
public readonly bool AutoEcho;

private readonly ulong stackCallSize;

Expand Down Expand Up @@ -69,7 +68,10 @@ public Processor(ulong memorySize, ulong entryPoint = 0,
UseV1CallStack = useV1CallStack;
stackCallSize = useV1CallStack ? 24UL : 16UL;
MapStack = mapStack;
AutoEcho = autoEcho;
if (autoEcho)
{
Registers[(int)Register.rsf] |= (ulong)StatusFlags.AutoEcho;
}
}

~Processor()
Expand Down Expand Up @@ -1536,7 +1538,7 @@ public bool Execute(bool runUntilHalt, Stream? stdoutOverride = null)
}
}
}
if (AutoEcho)
if ((Registers[(int)Register.rsf] & (ulong)StatusFlags.AutoEcho) != 0)
{
// Echo byte to console
stdout.WriteByte(currentByte);
Expand Down Expand Up @@ -2876,6 +2878,55 @@ is not (ulong)StatusFlags.Sign and not (ulong)StatusFlags.Overflow)
}
WriteMemoryRegister(operandStart, result);
break;
case 0x10: // Processor Info Query
switch (opcodeLow)
{
case 0x0: // EXTD_QPF reg
WriteMemoryRegister(operandStart, (ulong)AAPFeatures.All);
Registers[(ulong)Register.rpo]++;
break;
case 0x1: // EXTD_QPV reg
WriteMemoryRegister(operandStart, (ulong)(Program.version?.Major ?? 0));
Registers[(ulong)Register.rpo]++;
break;
case 0x2: // EXTD_QPV reg, reg
WriteMemoryRegister(operandStart, (ulong)(Program.version?.Major ?? 0));
WriteMemoryRegister(operandStart + 1, (ulong)(Program.version?.Minor ?? 0));
Registers[(ulong)Register.rpo] += 2;
break;
case 0x3: // EXTD_CSS reg
WriteMemoryRegister(operandStart, stackCallSize);
Registers[(ulong)Register.rpo]++;
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_Low_Extended_InfoQuery, opcodeLow));
}
break;
case 0x20: // Halt with Exit Code
switch (opcodeLow)
{
case 0x0: // EXTD_HLT reg
result = ReadMemoryRegister(operandStart);
Registers[(ulong)Register.rpo]++;
break;
case 0x1: // EXTD_HLT lit
result = ReadMemoryQWord(operandStart);
Registers[(ulong)Register.rpo] += 8;
break;
case 0x2: // EXTD_HLT adr
result = ReadMemoryPointedQWord(operandStart);
Registers[(ulong)Register.rpo] += 8;
break;
case 0x3: // EXTD_HLT ptr
result = ReadMemoryRegisterPointedQWord(operandStart);
Registers[(ulong)Register.rpo]++;
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_Low_Extended_Halt, opcodeLow));
}
Environment.ExitCode = (int)result;
halt = true;
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_High_Extended, opcodeHigh));
}
Expand Down Expand Up @@ -3059,7 +3110,7 @@ is not (ulong)StatusFlags.Sign and not (ulong)StatusFlags.Overflow)
case 0x20: // Exists
switch (opcodeLow)
{
case 0x0: // ASMX_AEX adr
case 0x0: // ASMX_AEX reg, adr
initial = ReadMemoryQWord(operandStart + 1);
mathend = 0;
while (Memory[initial + mathend] != 0x0)
Expand All @@ -3083,7 +3134,7 @@ is not (ulong)StatusFlags.Sign and not (ulong)StatusFlags.Overflow)
testLoadContext.Unload();
}
break;
case 0x1: // ASMX_AEX ptr
case 0x1: // ASMX_AEX reg, ptr
initial = ReadMemoryRegister(operandStart + 1);
mathend = 0;
while (Memory[initial + mathend] != 0x0)
Expand All @@ -3107,7 +3158,7 @@ is not (ulong)StatusFlags.Sign and not (ulong)StatusFlags.Overflow)
testLoadContext.Unload();
}
break;
case 0x2: // ASMX_FEX adr
case 0x2: // ASMX_FEX reg, adr
if (extLoadContext is null || openExtAssembly is null)
{
throw new ExternalOperationException(Strings.Processor_Error_Assembly_Not_Open);
Expand All @@ -3130,7 +3181,7 @@ is not (ulong)StatusFlags.Sign and not (ulong)StatusFlags.Overflow)
WriteMemoryRegister(operandStart, 0);
}
break;
case 0x3: // ASMX_FEX ptr
case 0x3: // ASMX_FEX reg, ptr
if (extLoadContext is null || openExtAssembly is null)
{
throw new ExternalOperationException(Strings.Processor_Error_Assembly_Not_Open);
Expand Down Expand Up @@ -3377,6 +3428,150 @@ is not (ulong)StatusFlags.Sign and not (ulong)StatusFlags.Overflow)
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_High_Allocation, opcodeHigh));
}
break;
case 0x7: // Terminal Extension Set
switch (opcodeHigh)
{
case 0x00: // Clear
switch (opcodeLow)
{
case 0x0: // TERM_CLS
Console.Clear();
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_Low_Terminal_Clear, opcodeLow));
}
break;
case 0x10: // Auto echo
switch (opcodeLow)
{
case 0x0: // TERM_AEE
Registers[(int)Register.rsf] |= (ulong)StatusFlags.AutoEcho;
break;
case 0x1: // TERM_AED
Registers[(int)Register.rsf] &= ~(ulong)StatusFlags.AutoEcho;
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_Low_Terminal_Clear, opcodeLow));
}
break;
case 0x20: // Set Cursor Position
switch (opcodeLow)
{
case 0x0: // TERM_SCY reg
Console.SetCursorPosition(Console.GetCursorPosition().Left, (int)ReadMemoryRegister(operandStart));
Registers[(int)Register.rpo]++;
break;
case 0x1: // TERM_SCY lit
Console.SetCursorPosition(Console.GetCursorPosition().Left, (int)ReadMemoryQWord(operandStart));
Registers[(int)Register.rpo] += 8;
break;
case 0x2: // TERM_SCY adr
Console.SetCursorPosition(Console.GetCursorPosition().Left, (int)ReadMemoryPointedQWord(operandStart));
Registers[(int)Register.rpo] += 8;
break;
case 0x3: // TERM_SCY ptr
Console.SetCursorPosition(Console.GetCursorPosition().Left, (int)ReadMemoryRegisterPointedQWord(operandStart));
Registers[(int)Register.rpo]++;
break;
case 0x4: // TERM_SCX reg
Console.SetCursorPosition((int)ReadMemoryRegister(operandStart), Console.GetCursorPosition().Top);
Registers[(int)Register.rpo]++;
break;
case 0x5: // TERM_SCX lit
Console.SetCursorPosition((int)ReadMemoryQWord(operandStart), Console.GetCursorPosition().Top);
Registers[(int)Register.rpo] += 8;
break;
case 0x6: // TERM_SCX adr
Console.SetCursorPosition((int)ReadMemoryPointedQWord(operandStart), Console.GetCursorPosition().Top);
Registers[(int)Register.rpo] += 8;
break;
case 0x7: // TERM_SCX ptr
Console.SetCursorPosition((int)ReadMemoryRegisterPointedQWord(operandStart), Console.GetCursorPosition().Top);
Registers[(int)Register.rpo]++;
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_Low_Terminal_SetPosition, opcodeLow));
}
break;
case 0x30: // Get Terminal Info
switch (opcodeLow)
{
case 0x0: // TERM_GCY reg
WriteMemoryRegister(operandStart, (ulong)Console.GetCursorPosition().Top);
Registers[(int)Register.rpo]++;
break;
case 0x1: // TERM_GCX reg
WriteMemoryRegister(operandStart, (ulong)Console.GetCursorPosition().Left);
Registers[(int)Register.rpo]++;
break;
case 0x2: // TERM_GSY reg
WriteMemoryRegister(operandStart, (ulong)Console.BufferHeight);
Registers[(int)Register.rpo]++;
break;
case 0x3: // TERM_GSX reg
WriteMemoryRegister(operandStart, (ulong)Console.BufferWidth);
Registers[(int)Register.rpo]++;
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_Low_Terminal_GetPosition, opcodeLow));
}
break;
case 0x40: // Beep
switch (opcodeLow)
{
case 0x0: // TERM_BEP
Console.Beep();
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_Low_Terminal_Beep, opcodeLow));
}
break;
case 0x50: // Set Colour
switch (opcodeLow)
{
case 0x0: // TERM_SFC reg
Console.ForegroundColor = (ConsoleColor)ReadMemoryRegister(operandStart);
Registers[(int)Register.rpo]++;
break;
case 0x1: // TERM_SFC lit
Console.ForegroundColor = (ConsoleColor)ReadMemoryQWord(operandStart);
Registers[(int)Register.rpo] += 8;
break;
case 0x2: // TERM_SFC adr
Console.ForegroundColor = (ConsoleColor)ReadMemoryPointedQWord(operandStart);
Registers[(int)Register.rpo] += 8;
break;
case 0x3: // TERM_SFC ptr
Console.ForegroundColor = (ConsoleColor)ReadMemoryRegisterPointedQWord(operandStart);
Registers[(int)Register.rpo]++;
break;
case 0x4: // TERM_SBC reg
Console.BackgroundColor = (ConsoleColor)ReadMemoryRegister(operandStart);
Registers[(int)Register.rpo]++;
break;
case 0x5: // TERM_SBC lit
Console.BackgroundColor = (ConsoleColor)ReadMemoryQWord(operandStart);
Registers[(int)Register.rpo] += 8;
break;
case 0x6: // TERM_SBC adr
Console.BackgroundColor = (ConsoleColor)ReadMemoryPointedQWord(operandStart);
Registers[(int)Register.rpo] += 8;
break;
case 0x7: // TERM_SBC ptr
Console.BackgroundColor = (ConsoleColor)ReadMemoryRegisterPointedQWord(operandStart);
Registers[(int)Register.rpo]++;
break;
case 0x8: // TERM_RSC
Console.ResetColor();
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_Low_Terminal_Colour, opcodeLow));
}
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_High_Terminal, opcodeHigh));
}
break;
default:
throw new InvalidOpcodeException(string.Format(Strings.Processor_Error_Opcode_Extension_Set, extensionSet));
}
Expand Down
Loading

0 comments on commit b9742be

Please sign in to comment.