~crc_/retro-ilo

2639eb64e4909dd4a2df56741924aa3eda999eb3 — crc 16 days ago f05e804
ilo.py: use dictionary of instructions now; start adding "superinstructions" to improve performance (on my system, startup is now 24s, down from 33s)

FossilOrigin-Name: 849b36df8e37cab499c14f59bef21c37963fda87bbc677febffb33fbe8d9c78a
1 files changed, 351 insertions(+), 161 deletions(-)

M vm/ilo.py
M vm/ilo.py => vm/ilo.py +351 -161
@@ 9,7 9,8 @@

import struct, io, os, sys, ctypes

class Stack():

class Stack:
    def __init__(self, size, desc):
        self.sp = 0
        self.data = [0] * size


@@ 18,7 19,7 @@ class Stack():

    def push(self, val):
        self.sp += 1
        if abs(val) > 0xffffff:
        if abs(val) > 0xFFFFFF:
            self.data[self.sp] = int(ctypes.c_int32(val).value)
        else:
            self.data[self.sp] = val


@@ 30,6 31,9 @@ class Stack():
    def top(self):
        return self.data[self.sp]

    def second(self):
        return self.data[self.sp - 1]

    def depth(self):
        return self.sp



@@ 38,24 42,26 @@ ip = 0
memory = [0]
input_buffer = []

data = Stack(33, 'data')
address = Stack(257, 'addresses')
data = Stack(33, "data")
address = Stack(257, "addresses")

block_pack = struct.Struct("1024i").pack
block_unpack = struct.Struct("1024i").unpack

block_pack = struct.Struct('1024i').pack
block_unpack = struct.Struct('1024i').unpack

def div_mod(a, b):
  x = abs(a)
  y = abs(b)
  q, r = divmod(x, y)
  if a < 0 and b < 0:
    r *= -1
  elif a > 0 and b < 0:
    q *= -1
  elif a < 0 and b > 0:
    r *= -1
    q *= -1
  return q, r
    x = abs(a)
    y = abs(b)
    q, r = divmod(x, y)
    if a < 0 and b < 0:
        r *= -1
    elif a > 0 and b < 0:
        q *= -1
    elif a < 0 and b > 0:
        r *= -1
        q *= -1
    return q, r


def load_image():
    global memory


@@ 65,162 71,349 @@ def load_image():

def save_image():
    with open("ilo.rom", "wb") as f:
        f.write(struct.pack('65536i', *memory[:65536]))
        f.write(struct.pack("65536i", *memory[:65536]))


def read_block():
    global memory, data
    buffer = data.pop()
    block = data.pop()
    with open("ilo.blocks", 'r+b') as f:
    with open("ilo.blocks", "r+b") as f:
        f.seek(4096 * block, io.SEEK_SET)
        memory[buffer:buffer+1024] = list(block_unpack(f.read(4096)))
        memory[buffer : buffer + 1024] = list(block_unpack(f.read(4096)))


def write_block():
    global data
    buffer = data.pop()
    block = data.pop()
    with open("ilo.blocks", 'r+b') as f:
    with open("ilo.blocks", "r+b") as f:
        f.seek(4096 * block, io.SEEK_SET)
        f.write(block_pack(*memory[buffer:buffer + 1024]))
        f.write(block_pack(*memory[buffer : buffer + 1024]))


def process(c):
def i00():
    global ip, data, address, memory, input_buffer


def i01():
    global ip, data, address, memory, input_buffer
    ip += 1
    data.push(memory[ip])


def i02():
    global ip, data, address, memory, input_buffer
    data.push(data.top())


def i03():
    global ip, data, address, memory, input_buffer
    data.pop()


def i04():
    global ip, data, address, memory, input_buffer
    a = data.pop()
    b = data.pop()
    data.push(a)
    data.push(b)


def i05():
    global ip, data, address, memory, input_buffer
    address.push(data.pop())


def i06():
    global ip, data, address, memory, input_buffer
    data.push(address.pop())


def i07():
    global ip, data, address, memory, input_buffer
    ip = data.pop() - 1


def i08():
    global ip, data, address, memory, input_buffer
    if c == 0: return
    address.push(ip)
    ip = data.pop() - 1


    if c == 11:
        ip = address.pop()
    elif c == 8:
def i09():
    global ip, data, address, memory, input_buffer
    target = data.pop()
    flag = data.pop()
    if flag != 0:
        address.push(ip)
        ip = data.pop() - 1
    elif c == 1:
        ip += 1
        data.push(memory[ip])
    elif c == 2:
        data.push(data.top())
    elif c == 3:
        data.pop()
    elif c == 4:
        a = data.pop()
        b = data.pop()
        data.push(a)
        data.push(b)
    elif c == 5:
        address.push(data.pop())
    elif c == 6:
        data.push(address.pop())
    elif c == 7:
        ip = data.pop() - 1
    elif c == 9:
        target = data.pop()
        flag = data.pop()
        if flag != 0:
            address.push(ip)
            ip = target - 1
    elif c == 10:
        target = data.pop()
        flag = data.pop()
        if flag != 0:
            ip = target - 1
    elif c == 12:
        b = data.pop()
        a = data.pop()
        data.push(-(a == b))
    elif c == 13:
        b = data.pop()
        a = data.pop()
        data.push(-(a != b))
    elif c == 14:
        b = data.pop()
        a = data.pop()
        data.push(-(a < b))
    elif c == 15:
        b = data.pop()
        a = data.pop()
        data.push(-(a > b))
    elif c == 16:
        x = data.pop()
        data.push(memory[x])
    elif c == 17:
        a = data.pop()
        v = data.pop()
        memory[a] = v
    elif c == 18:
        b = data.pop()
        a = data.pop()
        data.push(a + b)
    elif c == 19:
        b = data.pop()
        a = data.pop()
        data.push(a - b)
    elif c == 20:
        b = data.pop()
        a = data.pop()
        data.push(a * b)
    elif c == 21:
        a = data.pop()
        b = data.pop()
        data.push(div_mod(b, a)[1])
        data.push(div_mod(b, a)[0])
    elif c == 22:
        b = data.pop()
        a = data.pop()
        data.push(b & a)
    elif c == 23:
        b = data.pop()
        a = data.pop()
        data.push(b | a)
    elif c == 24:
        b = data.pop()
        a = data.pop()
        data.push(b ^ a)
    elif c == 25:
        b = data.pop()
        a = data.pop()
        data.push(a << b)
    elif c == 26:
        b = data.pop()
        a = data.pop()
        data.push(a >> b)
    elif c == 27:
        l = data.pop()
        dest = data.pop()
        src = data.pop()
        if memory[dest:dest + l] == memory[src:src + l]:
            data.push(-1)
        else:
            data.push(0)
    elif c == 28:
        l = data.pop()
        dest = data.pop()
        src = data.pop()
        memory[dest:dest + l] = memory[src:src + l]
    elif c == 29:
        i = data.pop()
        if i == 0:
            print(chr(data.pop()), end='')
        elif i == 1:
            if not len(input_buffer):
                input_buffer = ["\n"] + list(input())[::-1]
            data.push(ord(input_buffer.pop()))
        elif i == 2:
            read_block()
        elif i == 3:
            write_block()
        elif i == 4:
            save_image()
        elif i == 5:
            load_image()
            ip = -1
        elif i == 6:
            ip = 65535
        elif i == 7:
            data.push(data.depth())
            data.push(address.depth())
        ip = target - 1


def i10():
    global ip, data, address, memory, input_buffer
    target = data.pop()
    flag = data.pop()
    if flag != 0:
        ip = target - 1


def i11():
    global ip, data, address, memory, input_buffer
    ip = address.pop()


def i12():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(-(a == b))


def i13():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(-(a != b))


def i14():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(-(a < b))


def i15():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(-(a > b))


def i16():
    global ip, data, address, memory, input_buffer
    x = data.pop()
    data.push(memory[x])


def i17():
    global ip, data, address, memory, input_buffer
    a = data.pop()
    v = data.pop()
    memory[a] = v


def i18():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(a + b)


def i19():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(a - b)


def i20():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(a * b)


def i21():
    global ip, data, address, memory, input_buffer
    a = data.pop()
    b = data.pop()
    data.push(div_mod(b, a)[1])
    data.push(div_mod(b, a)[0])


def i22():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(b & a)


def i23():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(b | a)


def i24():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(b ^ a)


def i25():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(a << b)


def i26():
    global ip, data, address, memory, input_buffer
    b = data.pop()
    a = data.pop()
    data.push(a >> b)


def i27():
    global ip, data, address, memory, input_buffer
    l = data.pop()
    dest = data.pop()
    src = data.pop()
    if memory[dest : dest + l] == memory[src : src + l]:
        data.push(-1)
    else:
        pass
        data.push(0)


def i28():
    global ip, data, address, memory, input_buffer
    l = data.pop()
    dest = data.pop()
    src = data.pop()
    memory[dest : dest + l] = memory[src : src + l]


def i29():
    global ip, data, address, memory, input_buffer
    i = data.pop()
    if i == 0:
        print(chr(data.pop()), end="")
    elif i == 1:
        if not len(input_buffer):
            input_buffer = ["\n"] + list(input())[::-1]
        data.push(ord(input_buffer.pop()))
    elif i == 2:
        read_block()
    elif i == 3:
        write_block()
    elif i == 4:
        save_image()
    elif i == 5:
        load_image()
        ip = -1
    elif i == 6:
        ip = 65535
    elif i == 7:
        data.push(data.depth())
        data.push(address.depth())


def i2049():  # lica....
    global ip, data, address, memory, input_buffer
    address.push(ip + 1)
    ip = memory[ip + 1] - 1


def i1793():  # liju....
    global ip, data, address, memory, input_buffer
    ip = memory[ip + 1] - 1


def i524545():  # lilica..
    global ip, data, address, memory, input_buffer
    data.push(memory[ip + 1])
    address.push(ip + 2)
    ip = memory[ip + 2] - 1


def i459009():  # liliju..
    global ip, data, address, memory, input_buffer
    data.push(memory[ip + 1])
    ip = memory[ip + 2] - 1


def i67502597():  # puduposw "over"
    global ip, data, address, memory, input_buffer
    data.push(data.second())


def i17563906():  # dulieqli
    global ip, data, address, memory, input_buffer
    data.push(-(memory[ip + 1] == data.top()))
    data.push(memory[ip + 2])
    ip += 2


def i100926722():  # dupuswpo "tuck"
    global ip, data, address, memory, input_buffer
    a = data.pop()
    b = data.pop()
    data.push(a)
    data.push(b)
    data.push(a)


def i302059522():  # dufeliad
    global ip, data, address, memory, input_buffer
    data.push(memory[data.top()] + memory[ip + 1])
    ip += 1


def i2818():  # dure....
    global ip, data, address, memory, input_buffer
    data.push(data.top())
    ip = address.pop()


instructions = {
    1: i01,
    2: i02,
    3: i03,
    4: i04,
    5: i05,
    6: i06,
    7: i07,
    8: i08,
    9: i09,
    10: i10,
    11: i11,
    12: i12,
    13: i13,
    14: i14,
    15: i15,
    16: i16,
    17: i17,
    18: i18,
    19: i19,
    20: i20,
    21: i21,
    22: i22,
    23: i23,
    24: i24,
    25: i25,
    26: i26,
    27: i27,
    28: i28,
    29: i29,
    2049: i2049,
    1793: i1793,
    524545: i524545,
    459009: i459009,
    67502597: i67502597,
    7563906: i17563906,
    100926722: i100926722,
    302059522: i302059522,
    2818: i2818,
}


def process(c):
    if c in instructions:
        instructions[c]()


def print_opcode_bundle(opcode):


@@ 235,12 428,9 @@ def execute(start):
    ip = start
    while ip < 65536:
        m = memory[ip]
        if m == 2049:
            address.push(ip + 1)
            ip = memory[ip + 1] - 1
        elif m < 30 and m > 0:
            process(m)
        elif m != 0:
        if m in instructions:
            instructions[m]()
        else:
            process(m & 0xFF)
            process((m >> 8) & 0xFF)
            process((m >> 16) & 0xFF)


@@ 253,5 443,5 @@ def main():
    execute(0)


if __name__ == '__main__':
     main()
if __name__ == "__main__":
    main()