def compare_values(value1, value2, operator):
def is_hex(val):
try:
int(val, 16)
return True
except ValueError:
return False
def convert_value(val):
if isinstance(val, (int, float)):
return val
if is_hex(val):
return int(val, 16)
try:
return float(val) if '.' in val else int(val)
except ValueError:
raise ValueError(f"Invalid value: {val}")
value1 = convert_value(value1)
value2 = convert_value(value2)
if operator == "==":
return value1 == value2
elif operator == "!=":
return value1 != value2
elif operator == ">>":
return value1 > value2
elif operator == "<<":
return value1 < value2
elif operator == ">=":
return value1 >= value2
elif operator == "<=":
return value1 <= value2
else:
raise ValueError("Invalid comparison operator")
try:
from machine import ADC, Pin, PWM
from time import sleep
import sys
Terminated = False
Registers = {
"RA": 0,
"RB": 0,
"RC": 0,
"RD": 0,
"RE": 0,
}
Logic = {
"CMP": False,
"ADC26": 0,
"ADC27": 0,
"ADC28": 0,
"Pin": 0,
}
Stack = {}
with open("hasm.txt", "r") as file:
code = file.readlines()
ln = 0
while ln < len(code):
if Terminated:
break
line = code[ln].strip()
if not line:
ln += 1
continue
if line.startswith("test"):
print("TEST", Registers, Logic, Stack, "TEST")
if line.startswith("lda"):
value = line.split()[1]
try:
int_address = value[1:]
if int_address in Stack:
Registers["RA"] = float(Stack[int_address])
else:
if int_address in Logic and int_address != "CMP":
Registers["RA"] = float(Logic[int_address])
else:
Registers["RA"] = float(value)
except:
if int_address in Logic and int_address != "CMP":
Registers["RA"] = float(Logic[int_address])
else:
Registers["RA"] = float(value)
elif line.startswith("ldb"):
value = line.split()[1]
try:
int_address = value[1:]
if int_address in Stack:
Registers["RB"] = float(Stack[int_address])
else:
if int_address in Logic and int_address != "CMP":
Registers["RB"] = float(Logic[int_address])
else:
Registers["RB"] = float(value)
except:
if int_address in Logic and int_address != "CMP":
Registers["RB"] = float(Logic[int_address])
else:
Registers["RB"] = float(value)
elif line.startswith("ldc"):
value = line.split()[1]
try:
int_address = value[1:]
if int_address in Stack:
Registers["RC"] = float(Stack[int_address])
else:
if int_address in Logic and int_address != "CMP":
Registers["RC"] = float(Logic[int_address])
else:
Registers["RC"] = float(value)
except:
if int_address in Logic and int_address != "CMP":
Registers["RC"] = float(Logic[int_address])
else:
Registers["RC"] = float(value)
elif line.startswith("ldd"):
value = line.split()[1]
try:
int_address = value[1:]
if int_address in Stack:
Registers["RD"] = float(Stack[int_address])
else:
if int_address in Logic and int_address != "CMP":
Registers["RD"] = float(Logic[int_address])
else:
Registers["RD"] = float(value)
except:
if int_address in Logic and int_address != "CMP":
Registers["RD"] = float(Logic[int_address])
else:
Registers["RD"] = float(value)
elif line.startswith("lde"):
value = line.split()[1]
try:
int_address = value[1:]
if int_address in Stack:
Registers["RE"] = float(Stack[int_address])
else:
if int_address in Logic and int_address != "CMP":
Registers["RE"] = float(Logic[int_address])
else:
Registers["RE"] = float(value)
except:
if int_address in Logic and int_address != "CMP":
Registers["RE"] = float(Logic[int_address])
else:
Registers["RE"] = float(value)
elif line.startswith("ldstk"):
address = line.split()[1]
int_address = address[1:]
value = line.split()[2]
if value in Registers:
Stack[int_address] = float(Registers[value])
elif value.startswith("@"):
try:
Stack[int_address] = float(Stack[int(value[1:], 16)])
except:
Stack[int_address] = 0
else:
if int_address in Logic and int_address != "CMP":
Stack[int_address] = float(Logic[int_address])
else:
Stack[int_address] = float(value)
elif line.startswith("add"):
try:
value1 = float(Registers[str(line.split()[2])])
except KeyError:
try:
address = line.split()[2]
int_address = address[1:]
value1 = float(Stack[int_address])
except KeyError:
try:
value1 = float(Logic[line.split()[2]])
except KeyError:
value1 = float(line.split()[2])
try:
value2 = float(Registers[str(line.split()[3])])
except KeyError:
try:
address = line.split()[3]
int_address = address[1:]
value2 = float(Stack[int_address])
except KeyError:
try:
value2 = float(Logic[line.split()[3]])
except KeyError:
value2 = float(line.split()[3])
try:
variable = line.split()[1]
if variable.startswith("@"):
int_address = variable[1:]
Stack[int_address] = float(float(value1) + float(value2))
elif variable in Registers:
Registers[str(variable)] = float(float(value1) + float(value2))
elif variable in Logic and variable != "CMP":
Logic[str(variable)] = float(float(value1) + float(value2))
except:
pass
elif line.startswith("sub"):
try:
value1 = float(Registers[str(line.split()[2])])
except KeyError:
try:
address = line.split()[2]
int_address = address[1:]
value1 = float(Stack[int_address])
except KeyError:
try:
value1 = float(Logic[line.split()[2]])
except KeyError:
value1 = float(line.split()[2])
try:
value2 = float(Registers[str(line.split()[3])])
except KeyError:
try:
address = line.split()[3]
int_address = address[1:]
value2 = float(Stack[int_address])
except KeyError:
try:
value2 = float(Logic[line.split()[3]])
except KeyError:
value2 = float(line.split()[3])
try:
variable = line.split()[1]
if variable.startswith("@"):
int_address = variable[1:]
Stack[int_address] = float(float(value1) - float(value2))
elif variable in Registers:
Registers[str(variable)] = float(float(value1) - float(value2))
elif variable in Logic and variable != "CMP":
Logic[str(variable)] = float(float(value1) - float(value2))
except:
pass
elif line.startswith("mul"):
try:
value1 = float(Registers[str(line.split()[2])])
except KeyError:
try:
address = line.split()[2]
int_address = address[1:]
value1 = float(Stack[int_address])
except KeyError:
try:
value1 = float(Logic[line.split()[2]])
except KeyError:
value1 = float(line.split()[2])
try:
value2 = float(Registers[str(line.split()[3])])
except KeyError:
try:
address = line.split()[3]
int_address = address[1:]
value2 = float(Stack[int_address])
except KeyError:
try:
value2 = float(Logic[line.split()[3]])
except KeyError:
value2 = float(line.split()[3])
try:
variable = line.split()[1]
if variable.startswith("@"):
int_address = variable[1:]
Stack[int_address] = float(float(value1) * float(value2))
elif variable in Registers:
Registers[str(variable)] = float(float(value1) * float(value2))
elif variable in Logic and variable != "CMP":
Logic[str(variable)] = float(float(value1) * float(value2))
except:
pass
elif line.startswith("div"):
try:
value1 = float(Registers[str(line.split()[2])])
except KeyError:
try:
address = line.split()[2]
int_address = address[1:]
value1 = float(Stack[int_address])
except KeyError:
try:
value1 = float(Logic[line.split()[2]])
except KeyError:
value1 = float(line.split()[2])
try:
value2 = float(Registers[str(line.split()[3])])
except KeyError:
try:
address = line.split()[3]
int_address = address[1:]
value2 = float(Stack[int_address])
except KeyError:
try:
value2 = float(Logic[line.split()[3]])
except KeyError:
value2 = float(line.split()[3])
try:
variable = line.split()[1]
if variable.startswith("@"):
int_address = variable[1:]
Stack[int_address] = float(float(value1) / float(value2))
elif variable in Registers:
Registers[str(variable)] = float(float(value1) / float(value2))
elif variable in Logic and variable != "CMP":
Logic[str(variable)] = float(float(value1) / float(value2))
except:
pass
elif line.startswith("idiv"):
try:
value1 = float(Registers[str(line.split()[2])])
except KeyError:
try:
address = line.split()[2]
int_address = address[1:]
value1 = float(Stack[int_address])
except KeyError:
try:
value1 = float(Logic[line.split()[2]])
except KeyError:
value1 = float(line.split()[2])
try:
value2 = float(Registers[str(line.split()[3])])
except KeyError:
try:
address = line.split()[3]
int_address = address[1:]
value2 = float(Stack[int_address])
except KeyError:
try:
value2 = float(Logic[line.split()[3]])
except KeyError:
value2 = float(line.split()[3])
try:
variable = line.split()[1]
if variable.startswith("@"):
int_address = variable[1:]
Stack[int_address] = float(float(value1) // float(value2))
elif variable in Registers:
Registers[str(variable)] = float(float(value1) // float(value2))
elif variable in Logic and variable != "CMP":
Logic[str(variable)] = float(float(value1) // float(value2))
except:
pass
elif line.startswith("pow"):
try:
value1 = float(Registers[str(line.split()[2])])
except KeyError:
try:
address = line.split()[2]
int_address = address[1:]
value1 = float(Stack[int_address])
except KeyError:
try:
value1 = float(Logic[line.split()[2]])
except KeyError:
value1 = float(line.split()[2])
try:
value2 = float(Registers[str(line.split()[3])])
except KeyError:
try:
address = line.split()[3]
int_address = address[1:]
value2 = float(Stack[int_address])
except KeyError:
try:
value2 = float(Logic[line.split()[3]])
except KeyError:
value2 = float(line.split()[3])
try:
variable = line.split()[1]
if variable.startswith("@"):
int_address = variable[1:]
Stack[int_address] = float(float(value1) ^ float(value2))
elif variable in Registers:
Registers[str(variable)] = float(float(value1) ^ float(value2))
elif variable in Logic and variable != "CMP":
Logic[str(variable)] = float(float(value1) ^ float(value2))
except:
pass
elif line.startswith("relcmp"):
Logic["CMP"] = False
elif line.startswith("jmpc"):
if Logic["CMP"] == True:
jump_value = line.split()[1]
if jump_value.startswith("+"):
jump_target = int(jump_value[1:])
ln += jump_target
elif jump_value.startswith("-"):
jump_target = -int(jump_value[1:])
ln += jump_target
else:
ln = int(jump_value) - 1
if 0 <= ln < len(code):
continue
else:
Terminated = True
sys.exit(0)
elif line.startswith("jmpnc"):
if Logic["CMP"] == False:
jump_value = line.split()[1]
if jump_value.startswith("+"):
jump_target = int(jump_value[1:])
ln += jump_target
elif jump_value.startswith("-"):
jump_target = -int(jump_value[1:])
ln += jump_target
else:
ln = int(jump_value) - 1
if 0 <= ln < len(code):
continue
else:
Terminated = True
sys.exit(0)
elif line.startswith("jmp"):
jump_value = line.split()[1]
if jump_value.startswith("+"):
jump_target = int(jump_value[1:])
ln += jump_target
elif jump_value.startswith("-"):
jump_target = -int(jump_value[1:])
ln += jump_target
else:
ln = int(jump_value) - 1
if 0 <= ln < len(code):
continue
else:
Terminated = True
sys.exit(0)
elif line.startswith("cmp"):
try:
value1 = str(Registers[str(line.split()[1])])
except KeyError:
try:
address = line.split()[1]
int_address = address[1:]
value1 = str(Stack[int_address])
except KeyError:
if line.split()[1] in ["ADC26", "ADC27", "ADC28", "Pin"]:
value1 = str(float(Logic[str(line.split()[1])]))
else:
value1 = str(float(line.split()[1]))
operator = str(line.split()[2])
try:
value2 = str(Registers[str(line.split()[3])])
except KeyError:
try:
address = line.split()[3]
int_address = address[1:]
value2 = str(Stack[int_address])
except KeyError:
if line.split()[3] in ["ADC26", "ADC27", "ADC28", "Pin"]:
value1 = str(float(Logic[str(line.split()[3])]))
else:
value2 = str(float(line.split()[3]))
Logic["CMP"] = compare_values(eval(value1), eval(value2), operator)
elif line.startswith("syscall"):
if int(Registers["RA"]) == 1:
Terminated = True
sys.exit(0)
elif int(Registers["RA"]) == 2:
sleep(Registers["RB"])
elif int(Registers["RA"]) == 3:
Pin(int(Registers["RB"]), Pin.OUT).value(int(Registers["RC"]))
elif int(Registers["RA"]) == 4:
Logic["Pin"] = Pin(int(Registers["RB"]), Pin.IN, Pin.PULL_DOWN).value()
elif int(Registers["RA"]) == 5:
Logic["ADC" + f"{int(Registers['RB'])}"] = ADC(Pin(int(Registers["RB"]))).read_u16()
elif int(Registers["RA"]) == 6:
pwm_pin = PWM(Pin(int(Registers["RB"])))
pwm_pin.freq(int(Registers["RC"]))
if Registers["RD"] == 1:
if 0 <= Registers["RE"] <= 65536:
pwm_pin.duty_u16(int(Registers["RE"]))
elif 0 >= Registers["RE"]:
pwm_pin.duty_u16(0)
elif 100 <= Registers["RE"]:
pwm_pin.duty_u16(65535)
elif Registers["RD"] == 2:
if 0 <= Registers["RE"] <= 100:
duty_value = int((Registers["RE"] / 100) * 65535)
pwm_pin.duty_u16(duty_value)
elif 0 >= Registers["RE"]:
pwm_pin.duty_u16(0)
elif 100 <= Registers["RD"]:
pwm_pin.duty_u16(65535)
ln += 1
except KeyboardInterrupt:
sys.exit(0)
except Exception as E:
from machine import Pin
Pin(22, Pin.OUT).value(1)
print(E)
sys.exit(0)