коммит 12
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
prog.bin
|
||||||
|
main.asm
|
713
compiler.py
Normal file
713
compiler.py
Normal file
@@ -0,0 +1,713 @@
|
|||||||
|
# WARNING! ЭТОТ КОД - ПОЛНОЕ ГОВНИЩЕ
|
||||||
|
# Если вы Роман Сакутин - немедленно закройте данную страницу!!!
|
||||||
|
|
||||||
|
code = open("main.asm").read().strip().lower().split("\n")
|
||||||
|
program = bytearray()
|
||||||
|
n = 0
|
||||||
|
errors = 0
|
||||||
|
|
||||||
|
def get_arg_type(arg: str) -> str:
|
||||||
|
if arg in ["ax", "bx", "cx", "dx", "ex", "fx"]:
|
||||||
|
return "reg"
|
||||||
|
elif arg.isdecimal():
|
||||||
|
return "dec"
|
||||||
|
elif arg.startswith("0x") and all(c in "0123456789abcdefABCDEF" for c in arg[2:]) and len(arg) > 2:
|
||||||
|
return "hex"
|
||||||
|
return "unk"
|
||||||
|
|
||||||
|
def get_reg_hex(arg: str) -> int:
|
||||||
|
return int(arg[0], 16)
|
||||||
|
|
||||||
|
def get_hex(arg: str) -> int:
|
||||||
|
global errorsE
|
||||||
|
value = int(arg[2:], 16)
|
||||||
|
if value > 65535:
|
||||||
|
print(f"[err] line {n}: value too large")
|
||||||
|
errors += 1
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_dec(arg: str) -> int:
|
||||||
|
global errors
|
||||||
|
value = int(arg)
|
||||||
|
if value > 65535:
|
||||||
|
print(f"[err] line {n}: value too large")
|
||||||
|
errors += 1
|
||||||
|
return value
|
||||||
|
|
||||||
|
for line in code:
|
||||||
|
line = line.split(";")[0]
|
||||||
|
n += 1
|
||||||
|
args = line.split()
|
||||||
|
if len(args) == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if args[0].startswith(":") and args[0].endswith(":") and get_arg_type(args[0].replace(":", "")) == "hex":
|
||||||
|
value = get_hex(args[0].replace(":", ""))
|
||||||
|
program.extend([0xFF, value >> 8, value & 255])
|
||||||
|
|
||||||
|
elif args[0] == "hlt":
|
||||||
|
program.append(0x00)
|
||||||
|
|
||||||
|
elif args[0] == "mov":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: the first argument must be a register")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([1, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([reg, value >> 8, value & 255])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([reg, value >> 8, value & 255])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid second argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "jmp":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
exit(-1)
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "reg":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
program.extend([3, reg])
|
||||||
|
elif arg_type == "hex":
|
||||||
|
value = get_hex(args[1])
|
||||||
|
program.extend([2, value >> 8, value & 255])
|
||||||
|
elif arg_type == "dec":
|
||||||
|
value = get_dec(args[1])
|
||||||
|
program.extend([2, value >> 8, value & 255])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "cmp":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg" or arg2_type != "reg":
|
||||||
|
print(f"[err] line {n}: all two arguments must be registers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
|
||||||
|
program.extend([4, (reg1 << 4) + reg2])
|
||||||
|
|
||||||
|
elif args[0] == "je":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "hex":
|
||||||
|
value = get_hex(args[1])
|
||||||
|
program.extend([5, value >> 8, value & 255])
|
||||||
|
elif arg_type == "dec":
|
||||||
|
value = get_dec(args[1])
|
||||||
|
program.extend([5, value >> 8, value & 255])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "jne":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "hex":
|
||||||
|
value = get_hex(args[1])
|
||||||
|
program.extend([6, value >> 8, value & 255])
|
||||||
|
elif arg_type == "dec":
|
||||||
|
value = get_dec(args[1])
|
||||||
|
program.extend([6, value >> 8, value & 255])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "jg":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "hex":
|
||||||
|
value = get_hex(args[1])
|
||||||
|
program.extend([7, value >> 8, value & 255])
|
||||||
|
elif arg_type == "dec":
|
||||||
|
value = get_dec(args[1])
|
||||||
|
program.extend([7, value >> 8, value & 255])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "jl":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "hex":
|
||||||
|
value = get_hex(args[1])
|
||||||
|
program.extend([8, value >> 8, value & 255])
|
||||||
|
elif arg_type == "dec":
|
||||||
|
value = get_dec(args[1])
|
||||||
|
program.extend([8, value >> 8, value & 255])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "add":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: first argument must be integers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([0x10, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([0x30, value >> 8, value & 255, reg1])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([0x30, value >> 8, value & 255, reg1])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
|
||||||
|
elif args[0] == "sub":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: first argument must be integers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([0x11, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([0x31, value >> 8, value & 255, reg1])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([0x31, value >> 8, value & 255, reg1])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
|
||||||
|
elif args[0] == "inc":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "reg":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
program.extend([0x12, reg])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "dec":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "reg":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
program.extend([0x13, reg])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "mul":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: first argument must be integers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([0x14, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([0x32, value >> 8, value & 255, reg1])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([0x32, value >> 8, value & 255, reg1])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
|
||||||
|
elif args[0] == "div":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: first argument must be integers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([0x15, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([0x33, value >> 8, value & 255, reg1])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([0x33, value >> 8, value & 255, reg1])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
|
||||||
|
elif args[0] == "rod":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: first argument must be integers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([0x16, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([0x34, value >> 8, value & 255, reg1])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([0x34, value >> 8, value & 255, reg1])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
|
||||||
|
elif args[0] == "and":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg" or arg2_type != "reg":
|
||||||
|
print(f"[err] line {n}: all two arguments must be registers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
|
||||||
|
program.extend([0x17, (reg1 << 4) + reg2])
|
||||||
|
|
||||||
|
elif args[0] == "or":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg" or arg2_type != "reg":
|
||||||
|
print(f"[err] line {n}: all two arguments must be registers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
|
||||||
|
program.extend([0x18, (reg1 << 4) + reg2])
|
||||||
|
|
||||||
|
elif args[0] == "xor":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg" or arg2_type != "reg":
|
||||||
|
print(f"[err] line {n}: all two arguments must be registers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
|
||||||
|
program.extend([0x19, (reg1 << 4) + reg2])
|
||||||
|
|
||||||
|
elif args[0] == "not":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "reg":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
program.extend([0x1A, reg])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "shl":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: first argument must be integers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([0x1B, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([0x35, value >> 8, value & 255, reg1])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([0x35, value >> 8, value & 255, reg1])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
|
||||||
|
elif args[0] == "shr":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: first argument must be integers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([0x1C, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([0x36, value >> 8, value & 255, reg1])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([0x36, value >> 8, value & 255, reg1])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
|
||||||
|
elif args[0] == "save":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: first argument must be integers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([0x1D, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([0x37, value >> 8, value & 255, reg1])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([0x37, value >> 8, value & 255, reg1])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
|
||||||
|
elif args[0] == "load":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg":
|
||||||
|
print(f"[err] line {n}: first argument must be integers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
if arg2_type == "reg":
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
program.extend([0x1E, (reg1 << 4) + reg2])
|
||||||
|
elif arg2_type == "dec":
|
||||||
|
value = get_dec(args[2])
|
||||||
|
program.extend([0x38, value >> 8, value & 255, reg1])
|
||||||
|
elif arg2_type == "hex":
|
||||||
|
value = get_hex(args[2])
|
||||||
|
program.extend([0x38, value >> 8, value & 255, reg1])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
|
||||||
|
elif args[0] == "ret":
|
||||||
|
program.extend([0x20])
|
||||||
|
|
||||||
|
elif args[0] == "call":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "hex":
|
||||||
|
value = get_hex(args[1])
|
||||||
|
program.extend([0x21, value >> 8, value & 255])
|
||||||
|
elif arg_type == "dec":
|
||||||
|
value = get_dec(args[1])
|
||||||
|
program.extend([0x21, value >> 8, value & 255])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "wr":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg" or arg2_type != "reg":
|
||||||
|
print(f"[err] line {n}: all two arguments must be registers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
|
||||||
|
program.extend([0x40, (reg1 << 4) + reg2])
|
||||||
|
|
||||||
|
elif args[0] == "rd":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg" or arg2_type != "reg":
|
||||||
|
print(f"[err] line {n}: all two arguments must be registers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
|
||||||
|
program.extend([0x41, (reg1 << 4) + reg2])
|
||||||
|
|
||||||
|
elif args[0] == "awr":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg" or arg2_type != "reg":
|
||||||
|
print(f"[err] line {n}: all two arguments must be registers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
|
||||||
|
program.extend([0x42, (reg1 << 4) + reg2])
|
||||||
|
|
||||||
|
elif args[0] == "ard":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg" or arg2_type != "reg":
|
||||||
|
print(f"[err] line {n}: all two arguments must be registers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
|
||||||
|
program.extend([0x43, (reg1 << 4) + reg2])
|
||||||
|
|
||||||
|
elif args[0] == "del":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "reg":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
program.extend([0x44, reg])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "uwr":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "reg":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
program.extend([0x45, reg])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "del":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "reg":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
program.extend([0x46, reg])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "del":
|
||||||
|
if len(args) != 2:
|
||||||
|
print(f"[err] line {n}: one argument required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg_type = get_arg_type(args[1])
|
||||||
|
if arg_type == "reg":
|
||||||
|
reg = get_reg_hex(args[1])
|
||||||
|
program.extend([0x47, reg])
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: invalid argument")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif args[0] == "pin":
|
||||||
|
if len(args) != 3:
|
||||||
|
print(f"[err] line {n}: two arguments required")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
arg1_type = get_arg_type(args[1])
|
||||||
|
arg2_type = get_arg_type(args[2])
|
||||||
|
|
||||||
|
if arg1_type != "reg" or arg2_type != "reg":
|
||||||
|
print(f"[err] line {n}: all two arguments must be registers")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
reg1 = get_reg_hex(args[1])
|
||||||
|
reg2 = get_reg_hex(args[2])
|
||||||
|
|
||||||
|
program.extend([0x48, (reg1 << 4) + reg2])
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f"[err] line {n}: unknown instruction: {args[0]}")
|
||||||
|
errors += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
if errors > 0:
|
||||||
|
exit(1)
|
||||||
|
#print(list(map(hex, program)))
|
||||||
|
open("prog.bin", "wb").write(program)
|
238
interpreter.py
Normal file
238
interpreter.py
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
from ctypes import *
|
||||||
|
import time
|
||||||
|
|
||||||
|
RAM = []
|
||||||
|
for i in range(256):
|
||||||
|
RAM.append(c_uint8(0))
|
||||||
|
PC, CB, RW, LM = c_uint16(0), c_uint16(0), c_uint16(0), c_uint16(0)
|
||||||
|
REG = c_uint16(0), c_uint16(0), c_uint16(0), c_uint16(0), c_uint16(0), c_uint16(0)
|
||||||
|
PROG = open("prog.bin", "rb").read()
|
||||||
|
HALTED = False
|
||||||
|
SPEED_HZ = 1600
|
||||||
|
|
||||||
|
instr_bytes = {
|
||||||
|
0x00: 1,
|
||||||
|
0x01: 2,
|
||||||
|
0x0A: 3,
|
||||||
|
0x0B: 3,
|
||||||
|
0x0C: 3,
|
||||||
|
0x0D: 3,
|
||||||
|
0x0E: 3,
|
||||||
|
0x0F: 3,
|
||||||
|
0xFF: 3,
|
||||||
|
0x02: 3,
|
||||||
|
0x03: 2,
|
||||||
|
0x04: 2,
|
||||||
|
0x05: 3,
|
||||||
|
0x06: 3,
|
||||||
|
0x07: 3,
|
||||||
|
0x08: 3,
|
||||||
|
0x10: 2,
|
||||||
|
0x11: 2,
|
||||||
|
0x12: 2,
|
||||||
|
0x13: 2,
|
||||||
|
0x14: 2,
|
||||||
|
0x15: 2,
|
||||||
|
0x16: 2,
|
||||||
|
0x17: 2,
|
||||||
|
0x18: 2,
|
||||||
|
0x19: 2,
|
||||||
|
0x1A: 2,
|
||||||
|
0x1B: 2,
|
||||||
|
0x1C: 2,
|
||||||
|
0x1D: 2,
|
||||||
|
0x1E: 2,
|
||||||
|
0x20: 1,
|
||||||
|
0x21: 3,
|
||||||
|
0x40: 2,
|
||||||
|
0x41: 2,
|
||||||
|
0x42: 2,
|
||||||
|
0x43: 2,
|
||||||
|
0x44: 2,
|
||||||
|
0x45: 2,
|
||||||
|
0x46: 2,
|
||||||
|
0x47: 2,
|
||||||
|
0x48: 2,
|
||||||
|
0x30: 4,
|
||||||
|
0x31: 4,
|
||||||
|
0x32: 4,
|
||||||
|
0x33: 4,
|
||||||
|
0x34: 4,
|
||||||
|
0x35: 4,
|
||||||
|
0x36: 4,
|
||||||
|
0x37: 4,
|
||||||
|
0x38: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
def read_16(byte1: int, byte2: int) -> c_uint16:
|
||||||
|
return c_uint16((byte1 << 8) + byte2)
|
||||||
|
|
||||||
|
|
||||||
|
def debug():
|
||||||
|
print()
|
||||||
|
for i in range(0, len(RAM), 16):
|
||||||
|
print(f"0x{format(i, "04X")}: ", end="")
|
||||||
|
line = RAM[i:i + 16]
|
||||||
|
print(
|
||||||
|
" ".join(format(b.value, "02X") for b in line),
|
||||||
|
"".join(chr(b.value) if b.value >= 0x20 else " " for b in line)
|
||||||
|
)
|
||||||
|
|
||||||
|
print("AX:", REG[0].value)
|
||||||
|
print("BX:", REG[1].value)
|
||||||
|
print("CX:", REG[2].value)
|
||||||
|
print("DX:", REG[3].value)
|
||||||
|
print("EX:", REG[4].value)
|
||||||
|
print("FX:", REG[5].value)
|
||||||
|
print("CB:", CB.value)
|
||||||
|
print("LM:", LM.value)
|
||||||
|
|
||||||
|
while PC.value < len(PROG):
|
||||||
|
instr = PROG[PC.value]
|
||||||
|
if instr == 0xFF:
|
||||||
|
RW = read_16(PROG[PC.value + 1], PROG[PC.value + 2])
|
||||||
|
else:
|
||||||
|
RAM[RW.value] = c_uint16(PROG[PC.value])
|
||||||
|
for byte in PROG[PC.value + 1:PC.value + instr_bytes[instr]]:
|
||||||
|
RW.value += 1
|
||||||
|
RAM[RW.value] = c_uint16(byte)
|
||||||
|
RW.value += 1
|
||||||
|
PC.value += instr_bytes[instr]
|
||||||
|
|
||||||
|
PC.value = 0
|
||||||
|
|
||||||
|
while not HALTED and PC.value < len(RAM):
|
||||||
|
start_time = time.time()
|
||||||
|
instr = RAM[PC.value].value
|
||||||
|
x, y, z = RAM[PC.value + 1].value >> 4, RAM[PC.value + 1].value & 15, RAM[PC.value + 3].value
|
||||||
|
value = (RAM[PC.value + 1].value << 8) + RAM[PC.value + 2].value
|
||||||
|
PC.value += instr_bytes[instr]
|
||||||
|
|
||||||
|
if instr == 0x00:
|
||||||
|
HALTED = True
|
||||||
|
|
||||||
|
elif instr == 0x01:
|
||||||
|
if x == y:
|
||||||
|
REG[x - 10].value = 0
|
||||||
|
else:
|
||||||
|
REG[x - 10].value = REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr in [0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F]:
|
||||||
|
REG[instr - 10].value = value
|
||||||
|
|
||||||
|
elif instr == 0x02:
|
||||||
|
PC.value = value
|
||||||
|
|
||||||
|
elif instr == 0x03:
|
||||||
|
PC.value = REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x04:
|
||||||
|
if REG[x - 10].value == REG[y - 10].value: CB.value = 0
|
||||||
|
elif REG[x - 10].value > REG[y - 10].value: CB.value = 1
|
||||||
|
elif REG[x - 10].value < REG[y - 10].value: CB.value = 2
|
||||||
|
|
||||||
|
elif instr == 0x05 and CB.value == 0:
|
||||||
|
PC.value = value
|
||||||
|
|
||||||
|
elif instr == 0x06 and CB.value != 0:
|
||||||
|
PC.value = value
|
||||||
|
|
||||||
|
elif instr == 0x07 and CB.value == 1:
|
||||||
|
PC.value = value
|
||||||
|
|
||||||
|
elif instr == 0x08 and CB.value == 2:
|
||||||
|
PC.value = value
|
||||||
|
|
||||||
|
elif instr == 0x10:
|
||||||
|
REG[x - 10].value += REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x11:
|
||||||
|
REG[x - 10].value -= REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x12:
|
||||||
|
REG[y - 10].value += 1
|
||||||
|
|
||||||
|
elif instr == 0x13:
|
||||||
|
REG[y - 10].value -= 1
|
||||||
|
|
||||||
|
elif instr == 0x14:
|
||||||
|
REG[x - 10].value *= REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x15:
|
||||||
|
REG[x - 10].value //= REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x16:
|
||||||
|
REG[x - 10].value %= REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x17:
|
||||||
|
REG[x - 10].value &= REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x18:
|
||||||
|
REG[x - 10].value |= REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x19:
|
||||||
|
REG[x - 10].value ^= REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x1A:
|
||||||
|
REG[y - 10].value = (1 << 4) - 1 - REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x1B:
|
||||||
|
REG[x - 10].value <<= REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x1C:
|
||||||
|
REG[x - 10].value >>= REG[y - 10].value
|
||||||
|
|
||||||
|
elif instr == 0x1D:
|
||||||
|
val = REG[x - 10].value
|
||||||
|
addr = REG[y - 10].value
|
||||||
|
RAM[addr].value = val >> 8
|
||||||
|
RAM[addr + 1].value = val & 255
|
||||||
|
|
||||||
|
elif instr == 0x1E:
|
||||||
|
addr = REG[y - 10].value
|
||||||
|
REG[x - 10].value = (RAM[addr].value << 8) + RAM[addr + 1].value
|
||||||
|
|
||||||
|
elif instr == 0x20:
|
||||||
|
PC.value = LM.value
|
||||||
|
|
||||||
|
elif instr == 0x21:
|
||||||
|
LM.value = PC.value
|
||||||
|
PC.value = value
|
||||||
|
|
||||||
|
elif instr == 0x45:
|
||||||
|
print(chr(REG[y - 10].value), end="")
|
||||||
|
|
||||||
|
elif instr == 0x30:
|
||||||
|
REG[z - 10].value += value
|
||||||
|
|
||||||
|
elif instr == 0x31:
|
||||||
|
REG[z - 10].value += value
|
||||||
|
|
||||||
|
elif instr == 0x32:
|
||||||
|
REG[z - 10].value *= value
|
||||||
|
|
||||||
|
elif instr == 0x33:
|
||||||
|
REG[z - 10].value //= value
|
||||||
|
|
||||||
|
elif instr == 0x34:
|
||||||
|
REG[z - 10].value %= value
|
||||||
|
|
||||||
|
elif instr == 0x35:
|
||||||
|
REG[z - 10].value <<= value
|
||||||
|
|
||||||
|
elif instr == 0x36:
|
||||||
|
REG[z - 10].value >>= value
|
||||||
|
|
||||||
|
elif instr == 0x37:
|
||||||
|
val = REG[z - 10].value
|
||||||
|
RAM[value].value = val >> 8
|
||||||
|
RAM[value + 1].value = val & 255
|
||||||
|
|
||||||
|
elif instr == 0x38:
|
||||||
|
REG[z - 10].value = (RAM[value].value << 8) + RAM[value + 1].value
|
||||||
|
|
||||||
|
sleep_time = 1/SPEED_HZ - (time.time() - start_time )
|
||||||
|
if sleep_time > 0:
|
||||||
|
time.sleep(sleep_time)
|
||||||
|
|
||||||
|
debug()
|
Reference in New Issue
Block a user