Implemeted Flag support and flag CONSTS.
Implmeneted ALIAS assembler instruction, JBC & JBS instructions.
This commit is contained in:
		
							
								
								
									
										12
									
								
								FLAGS.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								FLAGS.md
									
									
									
									
									
								
							| @@ -8,11 +8,11 @@ Bits marked N/A read as zero and writing values will not have an effect. | |||||||
|  |  | ||||||
| ### Status | CONSTS | 0x00 | ### Status | CONSTS | 0x00 | ||||||
|  |  | ||||||
| |                 | 7   | 6   | 5   | 4   | 3   | 2   | 1   | 0   | | |                 | 8   | 7   | 6   | 5   | 4   | 3   | 2   | 1   | | ||||||
| | --------------- | --- | --- | --- | --- | --- | --- | --- | --- | | | --------------- | --- | --- | --- | --- | --- | --- | --- | --- | | ||||||
| | **Read/Write**  |     |     |     |     |     |     | R/W | R   | | | **Read/Write**  |     |     |     |     | R   | R/W | R/W | R   | | ||||||
| | **Defaults**    |     |     |     |     |     |     | 1   | X   | | | **Default **    |     |     |     |     | X   | 1   | 1   | X   | | ||||||
| | **Name**        | N/A | N/A | N/A | N/A | N/A | N/A | Enabled | Available | | | **Name**        | N/A | N/A | N/A | N/A | ReadAvailable | ReadBlock | Enabled | Available | | ||||||
|  |  | ||||||
| ### Cursor X | CONPOSX | 0x01 | ### Cursor X | CONPOSX | 0x01 | ||||||
|  |  | ||||||
| @@ -50,9 +50,9 @@ Trap status and settings | |||||||
| <!--  | <!--  | ||||||
| ### Name | ALIAS | 0x00 | ### Name | ALIAS | 0x00 | ||||||
|  |  | ||||||
| |                 | 7   | 6   | 5   | 4   | 3   | 2   | 1   | 0   | | |                 | 8   | 7   | 6   | 5   | 4   | 3   | 2   | 1   | | ||||||
| | --------------- | --- | --- | --- | --- | --- | --- | --- | --- | | | --------------- | --- | --- | --- | --- | --- | --- | --- | --- | | ||||||
| | **Read/Write**  |     |     |     |     |     |     |     |     | | | **Read/Write**  |     |     |     |     |     |     |     |     | | ||||||
| | **Defaults**    |     |     |     |     |     |     |     |     | | | **Default **    |     |     |     |     |     |     |     |     | | ||||||
| | **Name**        |     |     |     |     |     |     |     |     | | | **Name**        |     |     |     |     |     |     |     |     | | ||||||
| --> | --> | ||||||
							
								
								
									
										7
									
								
								SPEC.md
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								SPEC.md
									
									
									
									
									
								
							| @@ -71,8 +71,8 @@ | |||||||
| | 0x51 | JMP   | [#\|:]           | | | 0x51 | JMP   | [#\|:]           | | ||||||
| | 0x52 | JZ    | [R] [#\|:]       | | | 0x52 | JZ    | [R] [#\|:]       | | ||||||
| | 0x53 | JNZ   | [R] [#\|:]       | | | 0x53 | JNZ   | [R] [#\|:]       | | ||||||
| | 0x54 | JBS   | [R] [0-7] [#\|:] | | | 0x54 | JBS   | [R] [1-8] [#\|:] | | ||||||
| | 0x55 | JBC   | [R] [0-7] [#\|:] | | | 0x55 | JBC   | [R] [1-8] [#\|:] | | ||||||
| | **System** | | **System** | ||||||
| | 0x60 | SYS   | [0-255]          | Syscall, parameters depend on call | | 0x60 | SYS   | [0-255]          | Syscall, parameters depend on call | ||||||
|  |  | ||||||
| @@ -80,7 +80,8 @@ | |||||||
|  |  | ||||||
| | ASM    | Parameters | Notes        | | | ASM    | Parameters | Notes        | | ||||||
| | ------ | ---------- | ------------ | | | ------ | ---------- | ------------ | | ||||||
| | ORIGIN | [#]        | Sets the Memory Address for the next instruction |  | | ORIGIN | [#]        | Sets the Memory Address for the next instruction | ||||||
|  | | ALIAS  | X Y        | Replaces word X with word Y where X and Y are alpha numberic, only applies after the instruction | ||||||
|  |  | ||||||
| ## Program Format | ## Program Format | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ using System.Collections.Generic; | |||||||
| using System.Text; | using System.Text; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
|  | using System.Text.RegularExpressions; | ||||||
|  |  | ||||||
| namespace SVM | namespace SVM | ||||||
| { | { | ||||||
| @@ -28,8 +29,11 @@ namespace SVM | |||||||
|             ushort lastpos = 0; |             ushort lastpos = 0; | ||||||
|             string line; |             string line; | ||||||
|             string[] parts; |             string[] parts; | ||||||
|  |  | ||||||
|             Dictionary<string, ushort> markers = new Dictionary<string, ushort>(); |             Dictionary<string, ushort> markers = new Dictionary<string, ushort>(); | ||||||
|             Dictionary<string, List<ushort>> markerUses = new Dictionary<string, List<ushort>>(); |             Dictionary<string, List<ushort>> markerUses = new Dictionary<string, List<ushort>>(); | ||||||
|  |             Dictionary<string, string> aliases = new Dictionary<string, string>(); | ||||||
|  |  | ||||||
|             //Encode ops until memory section |             //Encode ops until memory section | ||||||
|             for (; i < lines.Length; i++) |             for (; i < lines.Length; i++) | ||||||
|             { |             { | ||||||
| @@ -46,6 +50,12 @@ namespace SVM | |||||||
|                     line = line.Replace("  ", " "); |                     line = line.Replace("  ", " "); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  |                 //Replace aliases | ||||||
|  |                 foreach(var alias in aliases) | ||||||
|  |                 { | ||||||
|  |                     line = Regex.Replace(line, string.Format(@"(^|\b){0}($|\b)", alias.Key), alias.Value); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 //Records marker locations |                 //Records marker locations | ||||||
|                 if (line.StartsWith(':')) |                 if (line.StartsWith(':')) | ||||||
|                 { |                 { | ||||||
| @@ -77,6 +87,18 @@ namespace SVM | |||||||
|                     if (mempos > lastpos) lastpos = mempos; |                     if (mempos > lastpos) lastpos = mempos; | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|  |                 if (op == "ALIAS") | ||||||
|  |                 { | ||||||
|  |                     Debug.Assert(parts.Length == 2); | ||||||
|  |                     var aliasParts = parts[1].Split(' ', 2); | ||||||
|  |                     Debug.Assert(aliasParts.Length == 2); | ||||||
|  |                     if (aliases.ContainsKey(aliasParts[0])) | ||||||
|  |                     { | ||||||
|  |                         aliases.Remove(aliasParts[0]); | ||||||
|  |                     } | ||||||
|  |                     aliases.Add(aliasParts[0], aliasParts[1]); | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 var instr = instructions.First(x => x.ASM == op); |                 var instr = instructions.First(x => x.ASM == op); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								SVM/Flag.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								SVM/Flag.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Reflection; | ||||||
|  | using System.Text; | ||||||
|  |  | ||||||
|  | namespace SVM | ||||||
|  | { | ||||||
|  |     abstract class Flag | ||||||
|  |     { | ||||||
|  |         public static Flag[] GetAllFlags() | ||||||
|  |         { | ||||||
|  |             var types = from t in Assembly.GetAssembly(typeof(Flag)).GetTypes() | ||||||
|  |                         where t.IsSubclassOf(typeof(Flag)) | ||||||
|  |                         select t; | ||||||
|  |  | ||||||
|  |             var flags = new List<Flag>(); | ||||||
|  |  | ||||||
|  |             foreach (var t in types) | ||||||
|  |             { | ||||||
|  |                 flags.Add((Flag)Activator.CreateInstance(t)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return flags.ToArray(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public abstract string ASM { get; } | ||||||
|  |         public abstract byte Address { get; } | ||||||
|  |  | ||||||
|  |         public abstract byte Read(VM vm); | ||||||
|  |         public abstract void Write(VM vm, byte val); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										51
									
								
								SVM/Flags/CONSTS.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								SVM/Flags/CONSTS.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | using SVM.Ports; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.Text; | ||||||
|  |  | ||||||
|  | namespace SVM.Flags | ||||||
|  | { | ||||||
|  |     class CONSTS : Flag | ||||||
|  |     { | ||||||
|  |         public const byte AVAILABLE = 1; | ||||||
|  |         public const byte ENABLED = 2; | ||||||
|  |         public const byte READBLOCK = 4; | ||||||
|  |         public const byte READAVAILABLE = 8; | ||||||
|  |  | ||||||
|  |         public override string ASM => "CONSTS"; | ||||||
|  |  | ||||||
|  |         public override byte Address => 0x00; | ||||||
|  |  | ||||||
|  |         public override byte Read(VM vm) | ||||||
|  |         { | ||||||
|  |             var port = vm.Ports[0] as ConsolePort; | ||||||
|  |             Debug.Assert(port != null); | ||||||
|  |  | ||||||
|  |             byte result = AVAILABLE; | ||||||
|  |             if (port.Enabled) | ||||||
|  |             { | ||||||
|  |                 result |= ENABLED; | ||||||
|  |             } | ||||||
|  |             if (port.ReadBlock) | ||||||
|  |             { | ||||||
|  |                 result |= READBLOCK; | ||||||
|  |             } | ||||||
|  |             if (Console.KeyAvailable) | ||||||
|  |             { | ||||||
|  |                 result |= READAVAILABLE; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override void Write(VM vm, byte val) | ||||||
|  |         { | ||||||
|  |             var port = vm.Ports[0] as ConsolePort; | ||||||
|  |             Debug.Assert(port != null); | ||||||
|  |  | ||||||
|  |             port.Enabled = (val & ENABLED) == ENABLED; | ||||||
|  |             port.ReadBlock = (val & READBLOCK) == READBLOCK; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										83
									
								
								SVM/Instructions/JBC.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								SVM/Instructions/JBC.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.Text; | ||||||
|  |  | ||||||
|  | namespace SVM.Instructions | ||||||
|  | { | ||||||
|  |     class JBC : Instruction | ||||||
|  |     { | ||||||
|  |         public override string ASM => "JBC"; | ||||||
|  |  | ||||||
|  |         public override byte OP => 0x55; | ||||||
|  |  | ||||||
|  |         public override byte[] Encode(string asm, Dictionary<string, ushort> markerRefs) | ||||||
|  |         { | ||||||
|  |             var parts = asm.Split(' '); | ||||||
|  |             Debug.Assert(parts.Length == 3); | ||||||
|  |  | ||||||
|  |             byte reg = Register.FromASM(parts[0]); | ||||||
|  |  | ||||||
|  |             byte bit = byte.Parse(parts[1]); | ||||||
|  |             Debug.Assert(bit >= 1 && bit <= 8); | ||||||
|  |  | ||||||
|  |             ushort loc = 0; | ||||||
|  |             if (parts[2].StartsWith(':') && markerRefs != null) | ||||||
|  |             { | ||||||
|  |                 markerRefs.Add(parts[2].Substring(1), 3); | ||||||
|  |             } | ||||||
|  |             else if (parts[2].StartsWith("0x", StringComparison.InvariantCultureIgnoreCase)) | ||||||
|  |             { | ||||||
|  |                 loc = ushort.Parse(parts[2].Substring(2), System.Globalization.NumberStyles.HexNumber); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 loc = ushort.Parse(parts[2]); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return new byte[] { OP, reg, bit, loc.HiByte(), loc.LoByte() }; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override byte[] Decode(VM vm) | ||||||
|  |         { | ||||||
|  |             var bc = vm.MEM.Subset(vm.PC, 4); | ||||||
|  |             vm.PC += 4; | ||||||
|  |             return bc; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override void Exec(VM vm, byte[] vars) | ||||||
|  |         { | ||||||
|  |             Debug.Assert(vars.Length == 4); | ||||||
|  |  | ||||||
|  |             byte reg = vars[0]; | ||||||
|  |             Debug.Assert(reg <= VM.REGISTERS); | ||||||
|  |  | ||||||
|  |             byte bit = vars[1]; | ||||||
|  |             Debug.Assert(bit >= 1 && bit <= 8); | ||||||
|  |  | ||||||
|  |             ushort loc = (ushort)((vars[2] << 8) + vars[3]); | ||||||
|  |  | ||||||
|  |             if (CheckJump(vm, reg, bit)) | ||||||
|  |             { | ||||||
|  |                 vm.PC = loc; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected virtual bool CheckJump(VM vm, byte reg, byte bit) | ||||||
|  |         { | ||||||
|  |             byte compare = (byte)(1 << bit - 1); | ||||||
|  |             return (vm.R[reg] & compare) == 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override string ToASM(byte[] vars) | ||||||
|  |         { | ||||||
|  |             Debug.Assert(vars.Length == 4); | ||||||
|  |             byte reg = vars[0]; | ||||||
|  |             Debug.Assert(reg <= VM.REGISTERS); | ||||||
|  |             byte bit = vars[1]; | ||||||
|  |             ushort loc = (ushort)((vars[2] << 8) + vars[3]); | ||||||
|  |  | ||||||
|  |             return string.Format("{0} {1} {2} {3}", ASM, Register.ToASM(reg), bit, string.Format("0x{0:X}", loc)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								SVM/Instructions/JBS.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								SVM/Instructions/JBS.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Text; | ||||||
|  |  | ||||||
|  | namespace SVM.Instructions | ||||||
|  | { | ||||||
|  |     class JBS : JBC | ||||||
|  |     { | ||||||
|  |         public override string ASM => "JBS"; | ||||||
|  |  | ||||||
|  |         public override byte OP => 0x54; | ||||||
|  |  | ||||||
|  |         protected override bool CheckJump(VM vm, byte reg, byte bit) | ||||||
|  |         { | ||||||
|  |             byte compare = (byte)(1 << bit - 1); | ||||||
|  |             return (vm.R[reg] & compare) == compare; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -44,7 +44,7 @@ namespace SVM.Instructions | |||||||
|  |  | ||||||
|         protected virtual void Run(VM vm, byte reg, byte bit) |         protected virtual void Run(VM vm, byte reg, byte bit) | ||||||
|         { |         { | ||||||
|             vm.R[reg] = (ushort)(vm.R[reg] << bit); |             vm.R[reg] = (ushort)(vm.R[reg] << bit-1); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public override string ToASM(byte[] vars) |         public override string ToASM(byte[] vars) | ||||||
|   | |||||||
| @@ -15,9 +15,7 @@ namespace SVM | |||||||
|         public const string MEMORY_ASM = "M"; |         public const string MEMORY_ASM = "M"; | ||||||
|         public const byte IMMEDIATE_CODE = 0x3; |         public const byte IMMEDIATE_CODE = 0x3; | ||||||
|         public const string IMMEDIATE_ASM = "I"; |         public const string IMMEDIATE_ASM = "I"; | ||||||
|         public const byte FLAG_CODE = 0x4; |         public const byte ADDRESS_CODE = 0x4; | ||||||
|         public const string FLAG_ASM = "F"; |  | ||||||
|         public const byte ADDRESS_CODE = 0x5; |  | ||||||
|         public const string ADDRESS_ASM = "A"; |         public const string ADDRESS_ASM = "A"; | ||||||
|  |  | ||||||
|         public const int SIZE = 3; |         public const int SIZE = 3; | ||||||
| @@ -30,7 +28,6 @@ namespace SVM | |||||||
|                 case REGISTER_ASM: return REGISTER_CODE; |                 case REGISTER_ASM: return REGISTER_CODE; | ||||||
|                 case MEMORY_ASM: return MEMORY_CODE; |                 case MEMORY_ASM: return MEMORY_CODE; | ||||||
|                 case IMMEDIATE_ASM: return IMMEDIATE_CODE; |                 case IMMEDIATE_ASM: return IMMEDIATE_CODE; | ||||||
|                 case FLAG_ASM: return FLAG_CODE; |  | ||||||
|                 case ADDRESS_ASM:return ADDRESS_CODE; |                 case ADDRESS_ASM:return ADDRESS_CODE; | ||||||
|                 default: throw new Exception("Invalid location type"); |                 default: throw new Exception("Invalid location type"); | ||||||
|             } |             } | ||||||
| @@ -43,7 +40,6 @@ namespace SVM | |||||||
|                 case REGISTER_CODE: return REGISTER_ASM; |                 case REGISTER_CODE: return REGISTER_ASM; | ||||||
|                 case MEMORY_CODE: return MEMORY_ASM; |                 case MEMORY_CODE: return MEMORY_ASM; | ||||||
|                 case IMMEDIATE_CODE: return IMMEDIATE_ASM; |                 case IMMEDIATE_CODE: return IMMEDIATE_ASM; | ||||||
|                 case FLAG_CODE: return FLAG_ASM; |  | ||||||
|                 case ADDRESS_CODE: return ADDRESS_ASM; |                 case ADDRESS_CODE: return ADDRESS_ASM; | ||||||
|                 default: throw new Exception("Invalid location type"); |                 default: throw new Exception("Invalid location type"); | ||||||
|             } |             } | ||||||
| @@ -59,7 +55,6 @@ namespace SVM | |||||||
|             switch(type) |             switch(type) | ||||||
|             { |             { | ||||||
|                 case PORT_CODE: |                 case PORT_CODE: | ||||||
|                 case FLAG_CODE: |  | ||||||
|                     loc = byte.Parse(locVal); |                     loc = byte.Parse(locVal); | ||||||
|                     break; |                     break; | ||||||
|                 case ADDRESS_CODE: |                 case ADDRESS_CODE: | ||||||
| @@ -127,14 +122,12 @@ namespace SVM | |||||||
|                     Debug.Assert(loc <= VM.REGISTERS); |                     Debug.Assert(loc <= VM.REGISTERS); | ||||||
|                     return vm.R[loc]; |                     return vm.R[loc]; | ||||||
|                 case MEMORY_CODE: |                 case MEMORY_CODE: | ||||||
|                     return vm.MEM[loc]; |                     return vm.Read(loc); | ||||||
|                 case IMMEDIATE_CODE: |                 case IMMEDIATE_CODE: | ||||||
|                     return loc; |                     return loc; | ||||||
|                 case FLAG_CODE: |  | ||||||
|                     throw new NotImplementedException(); |  | ||||||
|                 case ADDRESS_CODE: |                 case ADDRESS_CODE: | ||||||
|                     Debug.Assert(loc <= VM.REGISTERS); |                     Debug.Assert(loc <= VM.REGISTERS); | ||||||
|                     return vm.MEM[vm.R[loc]]; |                     return vm.Read(vm.R[loc]); | ||||||
|                 default: throw new Exception("Invalid location type"); |                 default: throw new Exception("Invalid location type"); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -151,15 +144,13 @@ namespace SVM | |||||||
|                     vm.R[loc] = val; |                     vm.R[loc] = val; | ||||||
|                     break; |                     break; | ||||||
|                 case MEMORY_CODE: |                 case MEMORY_CODE: | ||||||
|                     vm.MEM[loc] = (byte)(val & 0xFF); |                     vm.Write(loc, (byte)(val & 0xFF)); | ||||||
|                     break; |                     break; | ||||||
|                 case IMMEDIATE_CODE: |                 case IMMEDIATE_CODE: | ||||||
|                     throw new Exception("Invalid operation"); |                     throw new Exception("Invalid operation"); | ||||||
|                 case FLAG_CODE: |  | ||||||
|                     throw new NotImplementedException(); |  | ||||||
|                 case ADDRESS_CODE: |                 case ADDRESS_CODE: | ||||||
|                     Debug.Assert(loc <= VM.REGISTERS); |                     Debug.Assert(loc <= VM.REGISTERS); | ||||||
|                     vm.MEM[vm.R[loc]] = (byte)(val & 0xFF); |                     vm.Write(vm.R[loc], (byte)(val & 0xFF)); | ||||||
|                     break; |                     break; | ||||||
|                 default: |                 default: | ||||||
|                     throw new Exception("Invalid location type"); |                     throw new Exception("Invalid location type"); | ||||||
| @@ -176,7 +167,6 @@ namespace SVM | |||||||
|             switch(type) |             switch(type) | ||||||
|             { |             { | ||||||
|                 case PORT_CODE: |                 case PORT_CODE: | ||||||
|                 case FLAG_CODE: |  | ||||||
|                     return string.Format("{0}{1}", DecodeType(type), loc); |                     return string.Format("{0}{1}", DecodeType(type), loc); | ||||||
|                 case REGISTER_CODE: |                 case REGISTER_CODE: | ||||||
|                     return string.Format("R{0}", Register.ToASM((byte)loc)); |                     return string.Format("R{0}", Register.ToASM((byte)loc)); | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								SVM/PGM/FlagTest.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								SVM/PGM/FlagTest.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | ALIAS F_CONSTS          0xFF00 | ||||||
|  | ALIAS STR_ENABLED       0x100 | ||||||
|  | ALIAS STR_AVAILABLE     0x110 | ||||||
|  | ALIAS STR_READBLOCK     0x120 | ||||||
|  | ALIAS STR_READAVAILABLE 0x130 | ||||||
|  | ALIAS STR_YES           0x140 | ||||||
|  | ALIAS STR_NO            0x150 | ||||||
|  |  | ||||||
|  | ORIGIN 0 | ||||||
|  |         LOAD D M F_CONSTS       # Read the flag into reg D | ||||||
|  |  | ||||||
|  |         LOAD A I STR_ENABLED | ||||||
|  |         CALL :WSTR | ||||||
|  |         JBS D 2 :ENYES          # Check for enabled | ||||||
|  |         LOAD A I STR_NO         # Set str to NO if enabled bit not set | ||||||
|  |         JMP :ENWR | ||||||
|  | :ENYES  LOAD A I STR_YES | ||||||
|  | :ENWR   CALL :WSTR | ||||||
|  | 		CALL :WNL | ||||||
|  |  | ||||||
|  | 		LOAD A I STR_READAVAILABLE | ||||||
|  | 		CALL :WSTR | ||||||
|  | 		JBS D 4 :RAYES | ||||||
|  | 		LOAD A I STR_NO | ||||||
|  | 		JMP :RAWR | ||||||
|  | :RAYES  LOAD A I STR_YES | ||||||
|  | :RAWR   CALL :WSTR | ||||||
|  | 		CALL :WNL | ||||||
|  |  | ||||||
|  |         HALT | ||||||
|  |  | ||||||
|  | :WSTR   LOAD C RA | ||||||
|  | :WSTR_L LOAD A AC | ||||||
|  |         JZ A :WSTR_R | ||||||
|  |         SAVE A P0 | ||||||
|  |         INC C | ||||||
|  |         JMP :WSTR_L | ||||||
|  | :WSTR_R RET | ||||||
|  |  | ||||||
|  | :WNL    LOAD A I13 | ||||||
|  |         SAVE A P0 | ||||||
|  |         LOAD A I10 | ||||||
|  |         SAVE A P0 | ||||||
|  |         RET | ||||||
|  |  | ||||||
|  | MEMORY | ||||||
|  | 0x100 "Enabled " | ||||||
|  | 0x110 "Available " | ||||||
|  | 0x120 "ReadBlock " | ||||||
|  | 0x130 "ReadAvailable " | ||||||
|  | 0x140 "Yes" | ||||||
|  | 0x150 "No" | ||||||
| @@ -6,19 +6,32 @@ namespace SVM.Ports | |||||||
| { | { | ||||||
|     class ConsolePort : Port |     class ConsolePort : Port | ||||||
|     { |     { | ||||||
|  |         public bool Enabled { get; set; } | ||||||
|  |         public bool ReadBlock { get; set; } | ||||||
|  |  | ||||||
|         public ConsolePort(VM vm)  |         public ConsolePort(VM vm)  | ||||||
|             : base(vm) |             : base(vm) | ||||||
|         { } |         { | ||||||
|  |             Enabled = true; | ||||||
|  |             ReadBlock = true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         public override ushort Read() |         public override ushort Read() | ||||||
|         { |         { | ||||||
|             var result = Console.ReadKey(true); |             if (ReadBlock || Console.KeyAvailable) | ||||||
|             return (byte)result.KeyChar; |             { | ||||||
|  |                 var result = Console.ReadKey(true); | ||||||
|  |                 return (byte)result.KeyChar; | ||||||
|  |             } | ||||||
|  |             return 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public override void Write(byte val) |         public override void Write(byte val) | ||||||
|         { |         { | ||||||
|             Console.Write((char)val); |             if (Enabled) | ||||||
|  |             { | ||||||
|  |                 Console.Write((char)val); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ | |||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <None Remove="PGM\CALL.txt" /> |     <None Remove="PGM\CALL.txt" /> | ||||||
|  |     <None Remove="PGM\FlagTest.txt" /> | ||||||
|     <None Remove="PGM\HELLO.txt" /> |     <None Remove="PGM\HELLO.txt" /> | ||||||
|     <None Remove="PGM\LOGIC.txt" /> |     <None Remove="PGM\LOGIC.txt" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| @@ -17,6 +18,9 @@ | |||||||
|     <Content Include="PGM\CALL.txt"> |     <Content Include="PGM\CALL.txt"> | ||||||
|       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||||||
|     </Content> |     </Content> | ||||||
|  |     <Content Include="PGM\FlagTest.txt"> | ||||||
|  |       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||||||
|  |     </Content> | ||||||
|     <Content Include="PGM\HELLO.txt"> |     <Content Include="PGM\HELLO.txt"> | ||||||
|       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||||||
|     </Content> |     </Content> | ||||||
|   | |||||||
							
								
								
									
										43
									
								
								SVM/VM.cs
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								SVM/VM.cs
									
									
									
									
									
								
							| @@ -8,7 +8,7 @@ namespace SVM | |||||||
|     class VM |     class VM | ||||||
|     { |     { | ||||||
|         public const int REGISTERS = 4; |         public const int REGISTERS = 4; | ||||||
|         public const int PORTS = 8; |         public const int PORTS = 255; | ||||||
|         public const int STACKDEPTH = 16; |         public const int STACKDEPTH = 16; | ||||||
|         public const int MEMSIZE = 0xFFFF; |         public const int MEMSIZE = 0xFFFF; | ||||||
|  |  | ||||||
| @@ -20,18 +20,23 @@ namespace SVM | |||||||
|         public ushort[] STACK = new ushort[STACKDEPTH]; |         public ushort[] STACK = new ushort[STACKDEPTH]; | ||||||
|         public byte[] MEM = new byte[MEMSIZE]; |         public byte[] MEM = new byte[MEMSIZE]; | ||||||
|         public Port[] Ports = new Port[PORTS]; |         public Port[] Ports = new Port[PORTS]; | ||||||
|  |         public ushort FlagStart = 0xFF00; | ||||||
|  |  | ||||||
|         public int CycleDelay = 0; |         public int CycleDelay = 0; | ||||||
|  |  | ||||||
|         private Dictionary<byte, Instruction> instructions = new Dictionary<byte, Instruction>(); |         private Dictionary<byte, Instruction> instructions = new Dictionary<byte, Instruction>(); | ||||||
|  |         private Dictionary<byte, Flag> flags = new Dictionary<byte, Flag>(); | ||||||
|  |  | ||||||
|         public VM() |         public VM() | ||||||
|         { |         { | ||||||
|             var instrs = Instruction.GetAllInstructions(); |             foreach(var instr in Instruction.GetAllInstructions()) | ||||||
|             foreach(var instr in instrs) |  | ||||||
|             { |             { | ||||||
|                 instructions.Add(instr.OP, instr); |                 instructions.Add(instr.OP, instr); | ||||||
|             } |             } | ||||||
|  |             foreach(var flag in Flag.GetAllFlags()) | ||||||
|  |             { | ||||||
|  |                 flags.Add(flag.Address, flag); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             Ports[0] = new Ports.ConsolePort(this); |             Ports[0] = new Ports.ConsolePort(this); | ||||||
|             Reset(); |             Reset(); | ||||||
| @@ -72,11 +77,39 @@ namespace SVM | |||||||
|                 var pc = PC; |                 var pc = PC; | ||||||
|                 var instr = instructions[MEM[PC++]]; |                 var instr = instructions[MEM[PC++]]; | ||||||
|                 byte[] decoded = instr.Decode(this); |                 byte[] decoded = instr.Decode(this); | ||||||
|                 Console.Write("{4:X4} | A{0:X3} B{1:X3} C{2:X3} D{3:X3} | ", R[0], R[1], R[2], R[3], pc); |                 //Console.Write("{4:X4} | A{0:X3} B{1:X3} C{2:X3} D{3:X3} | ", R[0], R[1], R[2], R[3], pc); | ||||||
|                 Console.WriteLine("0x{0:X4} {1}", pc, instr.ToASM(decoded)); |                 //Console.WriteLine("{0}", instr.ToASM(decoded)); | ||||||
|                 instr.Exec(this, decoded); |                 instr.Exec(this, decoded); | ||||||
|                 //Console.ReadKey(true); |                 //Console.ReadKey(true); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public byte Read(ushort location) | ||||||
|  |         { | ||||||
|  |             if (location >= FlagStart && location < FlagStart + 0xFF) | ||||||
|  |             { | ||||||
|  |                 byte flagAddress = (byte)(location - FlagStart); | ||||||
|  |                 if (flags.ContainsKey(flagAddress)) | ||||||
|  |                 { | ||||||
|  |                     return flags[flagAddress].Read(this); | ||||||
|  |                 } | ||||||
|  |                 return 0; | ||||||
|  |             } | ||||||
|  |             return MEM[location]; | ||||||
|  |         } | ||||||
|  |         public void Write(ushort location, byte val) | ||||||
|  |         { | ||||||
|  |             if (location >= FlagStart && location < FlagStart + 0xFF) | ||||||
|  |             { | ||||||
|  |                 byte flagAddress = (byte)(location - FlagStart); | ||||||
|  |                 if (flags.ContainsKey(flagAddress)) | ||||||
|  |                 { | ||||||
|  |                     flags[flagAddress].Write(this, val); | ||||||
|  |                 } | ||||||
|  |             } else | ||||||
|  |             { | ||||||
|  |                 MEM[location] = val; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user