From 6b6375dee1de1c5495704d4f582679da33e2453d Mon Sep 17 00:00:00 2001 From: TollyH Date: Wed, 5 Jun 2024 12:07:55 +0100 Subject: [PATCH] Support getting input from stream --- Processor.cs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Processor.cs b/Processor.cs index 49e12dd..8239d37 100644 --- a/Processor.cs +++ b/Processor.cs @@ -179,6 +179,10 @@ public void LoadProgram(byte[] programData) /// depending on the value of . /// /// if execution should stop (HLT reached) - otherwise + /// + /// Must not be if console key presses are being used for the RCC instruction. + /// If , RCC becomes a no-op and does not increment rpo if no characters are currently available on the input stream. + /// /// /// Thrown if a program hasn't been loaded into this processor, or the processor has reached the end of allocated memory. /// @@ -194,7 +198,7 @@ public void LoadProgram(byte[] programData) /// Thrown if a division instruction is executed with a value of zero as the divisor. /// Thrown if an operation that requires a file to exist could not find the target file. /// Thrown if an operation that requires a directory to exist could not find the target directory. - public bool Execute(bool runUntilHalt, Stream? stdoutOverride = null) + public bool Execute(bool runUntilHalt, Stream? stdoutOverride = null, Stream? stdinOverride = null, bool waitForInputChar = true) { if (!ProgramLoaded) { @@ -204,13 +208,18 @@ public bool Execute(bool runUntilHalt, Stream? stdoutOverride = null) { throw new InvalidOperationException("The processor has reached the end of accessible memory."); } + if (!waitForInputChar && stdinOverride is null && !Console.IsInputRedirected) + { + throw new ArgumentException("waitForInputChar cannot be false when characters are being read from console key presses, not a stream."); + } bool halt = false; using Stream stdout = stdoutOverride ?? Console.OpenStandardOutput(); do { byte extensionSet; byte opcode; - if (Memory[Registers[(int)Register.rpo]] == Opcode.FullyQualifiedMarker) + bool fullOpcode = Memory[Registers[(int)Register.rpo]] == Opcode.FullyQualifiedMarker; + if (fullOpcode) { extensionSet = Memory[++Registers[(int)Register.rpo]]; opcode = Memory[++Registers[(int)Register.rpo]]; @@ -1592,11 +1601,20 @@ public bool Execute(bool runUntilHalt, Stream? stdoutOverride = null) // to be converted to UTF-8. do { - if (Console.IsInputRedirected) + if (stdinOverride is not null || Console.IsInputRedirected) { // The program input isn't connected to a terminal, // so we can't wait for a pressed key - read the stdin stream directly instead - pressedKeyChar = (char)Console.Read(); + do + { + signedInitial = stdinOverride?.ReadByte() ?? Console.Read(); + } while (waitForInputChar && signedInitial == -1); + if (signedInitial == -1) + { + Registers[(int)Register.rpo] -= fullOpcode ? 3UL : 1UL; + return false; + } + pressedKeyChar = (char)signedInitial; inputCharacter += pressedKeyChar; } else