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