Implemented updated spec.
Added new logic instructions and test program. ASM markers may now start a line with an instruction. Improved logic in location class.
This commit is contained in:
16
SPEC.txt
16
SPEC.txt
@@ -16,11 +16,11 @@ Marker (:) :XYZ
|
||||
|
||||
Locations (@)
|
||||
Code ASM Type Values
|
||||
0x0 P Port 0-255
|
||||
0x0 P Port 0-255 | 0xFF
|
||||
0x1 R Register A-D
|
||||
0x2 M Memory 0-65535
|
||||
0x3 I Immediate 0-65535 | 'a' | "a" | 0xFFFF
|
||||
0x4 F Flag 0-255
|
||||
0x2 M Memory 0-65535 | 0xFFFF
|
||||
0x3 # Immediate 0-65535 | 0xFFFF | 'a' | "a"
|
||||
0x4 F Flag 0-255 | 0xFF
|
||||
0x5 A Address In Register A-D
|
||||
|
||||
Instructions
|
||||
@@ -48,10 +48,10 @@ Code ASM
|
||||
0x31 AND R @
|
||||
0x32 OR R @
|
||||
0x33 XOR R @
|
||||
0x33 SHL R 0-8 Shift Left
|
||||
0x34 SHR R 0-8 Shift Right
|
||||
0x35 BTS R 0-8 Bit Set
|
||||
0x36 BTC R 0-8 Bit Clear
|
||||
0x34 SHL R 0-7 Shift Left
|
||||
0x35 SHR R 0-7 Shift Right
|
||||
0x36 BTS R 0-7 Bit Set
|
||||
0x37 BTC R 0-7 Bit Clear
|
||||
Stack
|
||||
0x40 CALL #|:
|
||||
0x41 RET
|
||||
|
||||
@@ -49,9 +49,17 @@ namespace SVM
|
||||
//Records marker locations
|
||||
if (line.StartsWith(':'))
|
||||
{
|
||||
markers.Add(line.Substring(1), mempos);
|
||||
var markerParts = line.Split(" ", 2);
|
||||
markers.Add(markerParts[0].Substring(1), mempos);
|
||||
if (markerParts.Length > 1 && !string.IsNullOrWhiteSpace(markerParts[1]))
|
||||
{
|
||||
line = markerParts[1].Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
parts = line.Split(" ", 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
var op = parts[0];
|
||||
@@ -122,6 +130,7 @@ namespace SVM
|
||||
}
|
||||
|
||||
byte[] lineData = new byte[0];
|
||||
parts[1] = parts[1].Trim();
|
||||
if (parts[1].StartsWith('\'') || parts[1].StartsWith('"'))
|
||||
{
|
||||
string asciiContent = string.Empty;
|
||||
|
||||
17
SVM/Instructions/AND.cs
Normal file
17
SVM/Instructions/AND.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class AND : ADD
|
||||
{
|
||||
public override string ASM => "AND";
|
||||
public override byte OP => 0x31;
|
||||
|
||||
protected override void Run(VM vm, byte reg, Location loc)
|
||||
{
|
||||
vm.R[reg] &= loc.Read(vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
SVM/Instructions/BTC.cs
Normal file
18
SVM/Instructions/BTC.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class BTC : SHL
|
||||
{
|
||||
public override string ASM => "BTC";
|
||||
|
||||
public override byte OP => 0x37;
|
||||
|
||||
protected override void Run(VM vm, byte reg, byte bit)
|
||||
{
|
||||
vm.R[reg] = (ushort)(vm.R[reg] & ~(1 << bit));
|
||||
}
|
||||
}
|
||||
}
|
||||
18
SVM/Instructions/BTS.cs
Normal file
18
SVM/Instructions/BTS.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class BTS : SHL
|
||||
{
|
||||
public override string ASM => "BTS";
|
||||
|
||||
public override byte OP => 0x36;
|
||||
|
||||
protected override void Run(VM vm, byte reg, byte bit)
|
||||
{
|
||||
vm.R[reg] = (ushort)(vm.R[reg] | 1 << bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ namespace SVM.Instructions
|
||||
|
||||
public override byte[] Encode(string asm, Dictionary<string, ushort> markerRefs)
|
||||
{
|
||||
Debug.Assert(asm.Length == 1);
|
||||
byte reg = Register.FromASM(asm);
|
||||
return new byte[] { OP, reg };
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class CLRI : Instruction
|
||||
{
|
||||
public override string ASM => "CLRI";
|
||||
|
||||
public override byte OP => 0x62;
|
||||
|
||||
public override byte[] Encode(string asm, Dictionary<string, ushort> markerRefs)
|
||||
{
|
||||
return new byte[] { OP };
|
||||
}
|
||||
|
||||
public override void Exec(VM vm, byte[] vars)
|
||||
{
|
||||
Debug.Assert(vars.Length == 0);
|
||||
vm.RI = 0;
|
||||
}
|
||||
|
||||
public override string ToASM(byte[] vars)
|
||||
{
|
||||
Debug.Assert(vars.Length == 0);
|
||||
return ASM;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class DECI : Instruction
|
||||
{
|
||||
public override string ASM => "DECI";
|
||||
|
||||
public override byte OP => 0x64;
|
||||
|
||||
public override byte[] Encode(string asm, Dictionary<string, ushort> markerRefs)
|
||||
{
|
||||
return new byte[] { OP };
|
||||
}
|
||||
|
||||
public override void Exec(VM vm, byte[] vars)
|
||||
{
|
||||
Debug.Assert(vars.Length == 0);
|
||||
vm.RI--;
|
||||
}
|
||||
|
||||
public override string ToASM(byte[] vars)
|
||||
{
|
||||
Debug.Assert(vars.Length == 0);
|
||||
return ASM;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class INCI : Instruction
|
||||
{
|
||||
public override string ASM => "INCI";
|
||||
|
||||
public override byte OP => 0x63;
|
||||
|
||||
public override byte[] Encode(string asm, Dictionary<string, ushort> markerRefs)
|
||||
{
|
||||
return new byte[] { OP };
|
||||
}
|
||||
|
||||
public override void Exec(VM vm, byte[] vars)
|
||||
{
|
||||
Debug.Assert(vars.Length == 0);
|
||||
vm.RI++;
|
||||
}
|
||||
|
||||
public override string ToASM(byte[] vars)
|
||||
{
|
||||
Debug.Assert(vars.Length == 0);
|
||||
return ASM;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class LOADI : Instruction
|
||||
{
|
||||
public override string ASM => "LOADI";
|
||||
|
||||
public override byte OP => 0x60;
|
||||
|
||||
public override byte[] Encode(string asm, Dictionary<string, ushort> markerRefs)
|
||||
{
|
||||
var reg = Register.FromASM(asm);
|
||||
return new byte[] { OP, reg };
|
||||
}
|
||||
|
||||
public override byte[] Decode(VM vm)
|
||||
{
|
||||
var reg = vm.MEM[vm.PC];
|
||||
vm.PC++;
|
||||
return new byte[] { reg };
|
||||
}
|
||||
|
||||
public override void Exec(VM vm, byte[] vars)
|
||||
{
|
||||
Debug.Assert(vars.Length == 1);
|
||||
var reg = vars[0];
|
||||
Debug.Assert(reg <= VM.REGISTERS);
|
||||
Run(vm, reg);
|
||||
}
|
||||
|
||||
protected virtual void Run(VM vm, byte reg)
|
||||
{
|
||||
vm.R[reg] = vm.MEM[vm.RI];
|
||||
}
|
||||
|
||||
public override string ToASM(byte[] vars)
|
||||
{
|
||||
return string.Format("{0} {1}", ASM, Register.ToASM(vars[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class SETI : LOADI
|
||||
class NOT : CLR
|
||||
{
|
||||
public override string ASM => "SETI";
|
||||
public override string ASM => "NOT";
|
||||
|
||||
public override byte OP => 0x65;
|
||||
public override byte OP => 0x30;
|
||||
|
||||
protected override void Run(VM vm, byte reg)
|
||||
{
|
||||
vm.RI = vm.R[reg];
|
||||
vm.R[reg] = (ushort)~vm.R[reg];
|
||||
}
|
||||
}
|
||||
}
|
||||
17
SVM/Instructions/OR.cs
Normal file
17
SVM/Instructions/OR.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class OR : ADD
|
||||
{
|
||||
public override string ASM => "OR";
|
||||
public override byte OP => 0x32;
|
||||
|
||||
protected override void Run(VM vm, byte reg, Location loc)
|
||||
{
|
||||
vm.R[reg] |= loc.Read(vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ namespace SVM.Instructions
|
||||
|
||||
public override string ToASM(byte[] vars)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return ASM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class SAVEI : LOADI
|
||||
{
|
||||
public override string ASM => "SAVEI";
|
||||
|
||||
public override byte OP => 0x61;
|
||||
|
||||
protected override void Run(VM vm, byte reg)
|
||||
{
|
||||
vm.MEM[vm.RI] = (byte)vm.R[reg];
|
||||
}
|
||||
}
|
||||
}
|
||||
60
SVM/Instructions/SHL.cs
Normal file
60
SVM/Instructions/SHL.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class SHL : Instruction
|
||||
{
|
||||
public override string ASM => "SHL";
|
||||
|
||||
public override byte OP => 0x34;
|
||||
|
||||
public override byte[] Encode(string asm, Dictionary<string, ushort> markerRefs)
|
||||
{
|
||||
var parts = asm.Split(" ");
|
||||
Debug.Assert(parts.Length == 2);
|
||||
byte reg = Register.FromASM(parts[0]);
|
||||
byte bit = byte.Parse(parts[1]);
|
||||
Debug.Assert(bit < 8);
|
||||
|
||||
return new byte[] { OP, reg, bit };
|
||||
}
|
||||
|
||||
public override byte[] Decode(VM vm)
|
||||
{
|
||||
var bc = vm.MEM.Subset(vm.PC, 2);
|
||||
vm.PC += 2;
|
||||
return bc;
|
||||
}
|
||||
|
||||
public override void Exec(VM vm, byte[] vars)
|
||||
{
|
||||
Debug.Assert(vars.Length == 2);
|
||||
|
||||
byte reg = vars[0];
|
||||
byte bit = vars[1];
|
||||
|
||||
Debug.Assert(reg <= VM.REGISTERS);
|
||||
Debug.Assert(bit < 8);
|
||||
|
||||
Run(vm, reg, bit);
|
||||
}
|
||||
|
||||
protected virtual void Run(VM vm, byte reg, byte bit)
|
||||
{
|
||||
vm.R[reg] = (ushort)(vm.R[reg] << bit);
|
||||
}
|
||||
|
||||
public override string ToASM(byte[] vars)
|
||||
{
|
||||
Debug.Assert(vars.Length == 2);
|
||||
|
||||
byte reg = vars[0];
|
||||
byte bit = vars[1];
|
||||
|
||||
return string.Format("{0} {1} {2}", ASM, Register.ToASM(reg), bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
SVM/Instructions/SHR.cs
Normal file
18
SVM/Instructions/SHR.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class SHR : SHL
|
||||
{
|
||||
public override string ASM => "SHR";
|
||||
|
||||
public override byte OP => 0x35;
|
||||
|
||||
protected override void Run(VM vm, byte reg, byte bit)
|
||||
{
|
||||
vm.R[reg] = (ushort)(vm.R[reg] >> bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
SVM/Instructions/XOR.cs
Normal file
18
SVM/Instructions/XOR.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SVM.Instructions
|
||||
{
|
||||
class XOR : ADD
|
||||
{
|
||||
public override string ASM => "XOR";
|
||||
|
||||
public override byte OP => 0x33;
|
||||
|
||||
protected override void Run(VM vm, byte reg, Location loc)
|
||||
{
|
||||
vm.R[reg] ^= loc.Read(vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
137
SVM/Location.cs
137
SVM/Location.cs
@@ -9,12 +9,16 @@ namespace SVM
|
||||
{
|
||||
public const byte PORT_CODE = 0x0;
|
||||
public const string PORT_ASM = "P";
|
||||
public const byte REG_CODE = 0x1;
|
||||
public const string REG_ASM = "R";
|
||||
public const byte MEM_CODE = 0x2;
|
||||
public const string MEM_ASM = "M";
|
||||
public const byte LITERAL_CODE = 0x3;
|
||||
public const string LITERAL_ASM = "L";
|
||||
public const byte REGISTER_CODE = 0x1;
|
||||
public const string REGISTER_ASM = "R";
|
||||
public const byte MEMORY_CODE = 0x2;
|
||||
public const string MEMORY_ASM = "M";
|
||||
public const byte IMMEDIATE_CODE = 0x3;
|
||||
public const string IMMEDIATE_ASM = "I";
|
||||
public const byte FLAG_CODE = 0x4;
|
||||
public const string FLAG_ASM = "F";
|
||||
public const byte ADDRESS_CODE = 0x5;
|
||||
public const string ADDRESS_ASM = "A";
|
||||
|
||||
public const int SIZE = 3;
|
||||
|
||||
@@ -23,9 +27,11 @@ namespace SVM
|
||||
switch (type)
|
||||
{
|
||||
case PORT_ASM: return PORT_CODE;
|
||||
case REG_ASM: return REG_CODE;
|
||||
case MEM_ASM: return MEM_CODE;
|
||||
case LITERAL_ASM: return LITERAL_CODE;
|
||||
case REGISTER_ASM: return REGISTER_CODE;
|
||||
case MEMORY_ASM: return MEMORY_CODE;
|
||||
case IMMEDIATE_ASM: return IMMEDIATE_CODE;
|
||||
case FLAG_ASM: return FLAG_CODE;
|
||||
case ADDRESS_ASM:return ADDRESS_CODE;
|
||||
default: throw new Exception("Invalid location type");
|
||||
}
|
||||
}
|
||||
@@ -34,38 +40,63 @@ namespace SVM
|
||||
switch (type)
|
||||
{
|
||||
case PORT_CODE: return PORT_ASM;
|
||||
case REG_CODE: return REG_ASM;
|
||||
case MEM_CODE: return MEM_ASM;
|
||||
case LITERAL_CODE: return LITERAL_ASM;
|
||||
case REGISTER_CODE: return REGISTER_ASM;
|
||||
case MEMORY_CODE: return MEMORY_ASM;
|
||||
case IMMEDIATE_CODE: return IMMEDIATE_ASM;
|
||||
case FLAG_CODE: return FLAG_ASM;
|
||||
case ADDRESS_CODE: return ADDRESS_ASM;
|
||||
default: throw new Exception("Invalid location type");
|
||||
}
|
||||
}
|
||||
|
||||
public static Location FromASM(string asm)
|
||||
{
|
||||
var parts = asm.Split(" ", 2);
|
||||
Debug.Assert(parts.Length > 0);
|
||||
byte type = EncodeType(parts[0]);
|
||||
Debug.Assert(asm.Length > 1);
|
||||
asm = asm.Replace(" ", "");
|
||||
byte type = EncodeType(asm[0].ToString());
|
||||
ushort loc = 0;
|
||||
Debug.Assert(parts.Length == 2);
|
||||
string locVal = parts[1];
|
||||
if (locVal.StartsWith('\'') || locVal.StartsWith('"'))
|
||||
string locVal = asm.Substring(1);
|
||||
switch(type)
|
||||
{
|
||||
Debug.Assert(locVal.Length > 1);
|
||||
loc = (byte)locVal[1];
|
||||
}
|
||||
else if (locVal.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
Debug.Assert(locVal.Length > 2);
|
||||
loc = ushort.Parse(locVal.Substring(2), System.Globalization.NumberStyles.HexNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
loc = ushort.Parse(locVal);
|
||||
case PORT_CODE:
|
||||
case FLAG_CODE:
|
||||
loc = byte.Parse(locVal);
|
||||
break;
|
||||
case ADDRESS_CODE:
|
||||
case REGISTER_CODE:
|
||||
loc = Register.FromASM(locVal);
|
||||
break;
|
||||
case MEMORY_CODE:
|
||||
loc = ReadNumber(locVal, true);
|
||||
break;
|
||||
case IMMEDIATE_CODE:
|
||||
loc = ReadNumber(locVal, false);
|
||||
break;
|
||||
}
|
||||
|
||||
return new Location(type, loc);
|
||||
}
|
||||
|
||||
private static ushort ReadNumber(string val, bool allowChar)
|
||||
{
|
||||
ushort converted;
|
||||
if (allowChar && (val.StartsWith('\'') || val.StartsWith('"')))
|
||||
{
|
||||
Debug.Assert(val.Length > 1);
|
||||
converted = (byte)val[1];
|
||||
}
|
||||
else if (val.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
Debug.Assert(val.Length > 2);
|
||||
converted = ushort.Parse(val.Substring(2), System.Globalization.NumberStyles.HexNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
converted = ushort.Parse(val);
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
public static Location FromByteCode(byte[] data, int start)
|
||||
{
|
||||
Debug.Assert(data.Length > start);
|
||||
@@ -90,13 +121,20 @@ namespace SVM
|
||||
switch (type)
|
||||
{
|
||||
case PORT_CODE:
|
||||
Debug.Assert(loc <= VM.PORTS);
|
||||
return vm.Ports[loc].Read();
|
||||
case REG_CODE:
|
||||
case REGISTER_CODE:
|
||||
Debug.Assert(loc <= VM.REGISTERS);
|
||||
return vm.R[loc];
|
||||
case MEM_CODE:
|
||||
case MEMORY_CODE:
|
||||
return vm.MEM[loc];
|
||||
case LITERAL_CODE:
|
||||
case IMMEDIATE_CODE:
|
||||
return loc;
|
||||
case FLAG_CODE:
|
||||
throw new NotImplementedException();
|
||||
case ADDRESS_CODE:
|
||||
Debug.Assert(loc <= VM.REGISTERS);
|
||||
return vm.MEM[vm.R[loc]];
|
||||
default: throw new Exception("Invalid location type");
|
||||
}
|
||||
}
|
||||
@@ -105,16 +143,24 @@ namespace SVM
|
||||
switch (type)
|
||||
{
|
||||
case PORT_CODE:
|
||||
vm.Ports[loc].Write((byte)val);
|
||||
Debug.Assert(loc <= VM.PORTS);
|
||||
vm.Ports[loc].Write((byte)(val & 0xFF));
|
||||
break;
|
||||
case REG_CODE:
|
||||
case REGISTER_CODE:
|
||||
Debug.Assert(loc <= VM.REGISTERS);
|
||||
vm.R[loc] = val;
|
||||
break;
|
||||
case MEM_CODE:
|
||||
vm.MEM[loc] = (byte)val;
|
||||
case MEMORY_CODE:
|
||||
vm.MEM[loc] = (byte)(val & 0xFF);
|
||||
break;
|
||||
case LITERAL_CODE:
|
||||
case IMMEDIATE_CODE:
|
||||
throw new Exception("Invalid operation");
|
||||
case FLAG_CODE:
|
||||
throw new NotImplementedException();
|
||||
case ADDRESS_CODE:
|
||||
Debug.Assert(loc <= VM.REGISTERS);
|
||||
vm.MEM[vm.R[loc]] = (byte)(val & 0xFF);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid location type");
|
||||
}
|
||||
@@ -122,14 +168,25 @@ namespace SVM
|
||||
|
||||
public byte[] Encode()
|
||||
{
|
||||
byte ub = (byte)((loc & 0xFF00) >> 8);
|
||||
byte lb = (byte)(loc & 0xFF);
|
||||
return new byte[] { type, ub, lb };
|
||||
return new byte[] { type, loc.HiByte(), loc.LoByte() };
|
||||
}
|
||||
|
||||
public string ToASM()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case PORT_CODE:
|
||||
case FLAG_CODE:
|
||||
return string.Format("{0}{1}", DecodeType(type), loc);
|
||||
case REGISTER_CODE:
|
||||
return string.Format("R{0}", Register.ToASM((byte)loc));
|
||||
case ADDRESS_CODE:
|
||||
return string.Format("A{0}", Register.ToASM((byte)loc));
|
||||
case IMMEDIATE_CODE:
|
||||
case MEMORY_CODE:
|
||||
default:
|
||||
return string.Format("{0}0x{1:X}", DecodeType(type), loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
ORIGIN 0
|
||||
JMP :PGM
|
||||
|
||||
:WRITESTR
|
||||
SETI A
|
||||
:WRITESTR_LOOP
|
||||
LOADI A
|
||||
JZ A :WRITESTR_RET
|
||||
:WRITESTR LOAD C RA
|
||||
:WRITESTR_L LOAD A AC
|
||||
JZ A :WRITESTR_R
|
||||
SAVE A P0
|
||||
INCI
|
||||
JMP :WRITESTR_LOOP
|
||||
:WRITESTR_RET
|
||||
INC C
|
||||
JMP :WRITESTR_L
|
||||
:WRITESTR_R CLR C
|
||||
RET
|
||||
|
||||
:WRITENL
|
||||
LOAD A L 13
|
||||
:WRITENL LOAD A I13
|
||||
SAVE A P0
|
||||
LOAD A L 10
|
||||
LOAD A I10
|
||||
SAVE A P0
|
||||
RET
|
||||
|
||||
:PGM
|
||||
LOAD A L 0x100
|
||||
:PGM LOAD A I0x100
|
||||
CALL :WRITESTR
|
||||
CALL :WRITENL
|
||||
HALT
|
||||
|
||||
@@ -2,36 +2,33 @@
|
||||
#Print string 5 times
|
||||
|
||||
CLR B
|
||||
ADD B L 5
|
||||
ADD B L 48
|
||||
ADD B I5
|
||||
ADD B I48
|
||||
SAVE B P0
|
||||
SUB B L 48
|
||||
SUB B I48
|
||||
|
||||
LOAD A L 0x300 #Set string start
|
||||
SETI A
|
||||
JMP :PRINTA
|
||||
LOAD C I0x300 #Set string start
|
||||
|
||||
:PRINTA #Print until zero
|
||||
LOADI A
|
||||
LOAD A AC
|
||||
JZ A :NEWLINE
|
||||
SAVE A P0
|
||||
INCI
|
||||
INC C
|
||||
JMP :PRINTA
|
||||
|
||||
:NEWLINE #New Line
|
||||
LOAD A L 13
|
||||
LOAD A I13
|
||||
SAVE A P0
|
||||
LOAD A L 10
|
||||
LOAD A I10
|
||||
SAVE A P0
|
||||
|
||||
LOAD A L 0x300 #Set string start
|
||||
SETI A
|
||||
LOAD C I0x300 #Set string start
|
||||
|
||||
DEC B #Check Counter and stop if 5 printed
|
||||
JZ B :STOP
|
||||
ADD B L 48
|
||||
ADD B I48
|
||||
SAVE B P0
|
||||
SUB B L 48
|
||||
SUB B I48
|
||||
JMP :PRINTA
|
||||
|
||||
:STOP
|
||||
|
||||
11
SVM/PGM/LOGIC.txt
Normal file
11
SVM/PGM/LOGIC.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
ORIGIN 0
|
||||
LOAD A I1
|
||||
JMP :PGM
|
||||
|
||||
:PGM SHL A 1
|
||||
NOT A
|
||||
NOT A
|
||||
JZ A :EXIT
|
||||
JMP :PGM
|
||||
|
||||
:EXIT HALT
|
||||
@@ -10,6 +10,7 @@
|
||||
<ItemGroup>
|
||||
<None Remove="PGM\CALL.txt" />
|
||||
<None Remove="PGM\HELLO.txt" />
|
||||
<None Remove="PGM\LOGIC.txt" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -19,6 +20,9 @@
|
||||
<Content Include="PGM\HELLO.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="PGM\LOGIC.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -72,8 +72,8 @@ namespace SVM
|
||||
var pc = PC;
|
||||
var instr = instructions[MEM[PC++]];
|
||||
byte[] decoded = instr.Decode(this);
|
||||
//Console.WriteLine("A{0} B{1} C{2} D{3}", R[0], R[1], R[2], R[3]);
|
||||
//Console.WriteLine("0x{0:X4} {1}", pc, instr.ToASM(decoded));
|
||||
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));
|
||||
instr.Exec(this, decoded);
|
||||
//Console.ReadKey(true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user