Files
pasm/interpreter.py
2025-06-06 00:05:25 +03:00

239 lines
5.3 KiB
Python

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()