Пример #1
0
class ProgramCounter(Component):
    def __init__(self, n):
        super().__init__("pc " + n)
        self.v = 0
        self.addr = Signal(self, "addr", 8)
        self.data = Signal(self, "data", 8)
        self.rst = NotifySignal(self, "rst", 1)
        self.inc = NotifySignal(self, "inc", 1)
        self.we = NotifySignal(self, "we", 1)
        self.co = Signal(self, "co", 1)

    def update(self, signal):
        if self.rst.value() == 1:
            self.v = 0
        elif self.we.value():
            self.v = self.data.value()
            # print('Jump')
        elif self.inc.had_edge(0, 1):
            if self.v == 0xFF:
                self.v = 0
                self.co <<= 1
            else:
                self.v += 1
                self.co <<= 0
        self.addr <<= self.v
Пример #2
0
class RamIndex(Component):
    def __init__(self):
        super().__init__("ram_index")
        self.addr = NotifySignal(self, "addr", 12)
        self.x = NotifySignal(self, "x", 8)
        self.out = Signal(self, "out", 12)
        self.en = NotifySignal(self, "en", 1)

    def update(self, signal):
        if self.en.value():
            # print('offset by {}'.format(self.x.value()))
            self.out <<= self.addr.value() + self.x.value()
        else:
            self.out <<= self.addr.value()
Пример #3
0
class ALU(Component):
    def __init__(self):
        super().__init__("alu")
        self.a = Signal(self, "a", 9)
        self.b = Signal(self, "b", 8)
        self.out = Signal(self, "out", 9)
        self.fn = Signal(self, "fn", 1)
        self.oe = NotifySignal(self, "oe", 1)
        self.we = NotifySignal(self, "we", 1)
        self.v = 0

    def update(self, signal):
        if self.we.had_edge(0, 1):
            if self.fn.value() == 0:
                # nor
                trace("alu nor {} {}".format(self.a.value(), self.b.value()),
                      end="")
                carry = self.a.value() & 0b100000000
                value = self.a.value() & 0xFF
                self.v = carry | ((~(value | self.b.value())) & 0xFF)
            else:
                # add
                trace("alu add {} {}".format(self.a.value(), self.b.value()),
                      end="")
                self.v = ((self.a.value() & 0xFF) + self.b.value()) & 0x1FF

            trace(" --> {}".format(self.v))

        if self.oe.value() == 1:
            self.out <<= self.v
        else:
            self.out <<= None
Пример #4
0
class Decoder(Component):
    def __init__(self):
        super().__init__("decoder")
        self.clk = NotifySignal(self, "clk", 1)
        self.addr = Signal(self, "addr", 6)
        self.data = Signal(self, "data", 8)
        self.we = Signal(self, "we", 1)
        self.oe = Signal(self, "oe", 1)
        self.acc = 0
        self.adreg = 0
        self.pc = 0
        self.states = 0

    def reset(self):
        self.addr <<= 0
        self.data <<= None
        self.oe <<= 1
        self.we <<= 0

    def update(self, signal):
        if self.clk.had_edge(0, 1):
            if self.states == 0b000:
                self.pc = self.adreg + 1
                self.adreg = self.data.value()
            else:
                self.adreg = self.pc

            # ALU / Data Path
            if self.states == 0b010:
                # print('  add a {} + {}'.format(self.acc, self.data.value()))
                self.acc = ((self.acc & 0xFF) + self.data.value()) & 0x1FF
                # print('    = {}'.format(self.acc))
            elif self.states == 0b011:
                # print('  nor a {} + {}'.format(self.acc, self.data.value()))
                carry = self.acc & 0b100000000
                value = self.acc & 0xFF
                nor = (~(value | self.data.value())) & 0xFF
                self.acc = carry | nor
                # print('    = {}'.format(self.acc))
            elif self.states == 0b101:
                # Clear carry
                self.acc = self.acc & 0xFF

            # State machine
            if self.states != 0b000:
                self.states = 0b000
            elif (self.data.value()
                  & 0b11000000) == 0b11000000 and self.acc & 0b100000000:
                self.states = 0b101
            else:
                self.states = ~((self.data.value() >> 6) & 0b11) & 0b11

        clk = self.clk.value()
        self.addr <<= self.adreg & 0x3F
        self.data <<= None if self.states != 0b001 else self.acc & 0xFF
        self.oe <<= (0 if (clk == 1 or self.states == 0b001
                           or self.states == 0b101) else 1)
        self.we <<= 0 if (clk == 1 or self.states != 0b001) else 1
Пример #5
0
class InstructionRegister(Component):
    def __init__(self):
        super().__init__("ir")
        self.v = 0
        self.data = Signal(self, "data", 8)
        self.instr = Signal(self, "instr", 8)
        self.imm = Signal(self, "imm", 8)
        self.we = NotifySignal(self, "we", 1)
        self.oe = NotifySignal(self, "oe", 1)

    def update(self, signal):
        if self.we.had_edge(0, 1):
            self.v = self.data.value()
            self.instr <<= self.v
        if self.oe.value():
            imm = self.v & 0xF
            self.imm <<= imm | (imm << 4)
        else:
            self.imm <<= None
Пример #6
0
class Decoder(Component):
    def __init__(self):
        super().__init__("decoder")

        self.clk = NotifySignal(self, "clk", 1)

        self.ram_oe = Signal(self, "ram_oe", 1)
        self.ram_we = Signal(self, "ram_oe", 1)
        self.ar_oe = Signal(self, "ar_oe", 1)
        self.ar_we = Signal(self, "ar_we", 1)
        self.ir_oe = Signal(self, "ir_oe", 1)
        self.ir_we = Signal(self, "ir_we", 1)
        self.pc_we = Signal(self, "pc_we", 1)
        self.pc_oe = Signal(self, "pc_oe", 1)
        self.pc_inc = Signal(self, "pc_inc", 1)
        self.a_oe = Signal(self, "a_oe", 1)
        self.a_we = Signal(self, "a_we", 1)
        self.a_cc = Signal(self, "a_cc", 1)
        self.x_oe = Signal(self, "a_oe", 1)
        self.x_we = Signal(self, "a_we", 1)
        self.alu_oe = Signal(self, "alu_oe", 1)
        self.alu_we = Signal(self, "alu_we", 1)
        self.idx_en = Signal(self, "idx_en", 1)

        self.carry = Signal(self, "carry", 1)
        self.z = Signal(self, "z", 1)

        self.instr = Signal(self, "instr", 3)

        self.state = 0
        self.last_clk = None

    def reset(self):
        self.ram_oe <<= 0
        self.ram_we <<= 0
        self.ar_oe <<= 0
        self.ar_we <<= 0
        self.ir_oe <<= 0
        self.ir_we <<= 0
        self.pc_we <<= 0
        self.pc_oe <<= 0
        self.pc_inc <<= 0
        self.a_oe <<= 0
        self.a_we <<= 0
        self.a_cc <<= 0
        self.x_oe <<= 0
        self.x_we <<= 0
        self.alu_oe <<= 1
        self.alu_we <<= 0
        self.idx_en <<= 0

    def update(self, signal):
        if self.clk.value() != self.last_clk:
            self.state = (self.state + 1) % 8
            self.last_clk = self.clk.value()
        else:
            return
            # print('state: {}: instr: {:02b}'.format(self.state, self.instr.value()))

        self.ram_oe <<= self.state <= 3 or (self.instr.value()
                                            in (0b000, 0b001, 0b100, 0b101)
                                            and self.state <= 5)

        self.ar_oe <<= self.state > 3
        self.ir_oe <<= self.state > 3
        self.pc_oe <<= self.state <= 3
        self.ir_we <<= self.state == 1
        self.pc_inc <<= self.state in (
            2,
            4,
        )
        self.ar_we <<= self.state == 3

        # alu
        self.alu_we <<= (self.instr.value() in (0b000, 0b001, 0b100, 0b101)
                         and self.state == 5)
        # self.alu_oe <<= self.instr.value() in (0b000, 0b001, 0b100, 0b101) and self.state in (5, 6,)
        self.a_we <<= (self.instr.value() in (
            0b000,
            0b001,
        ) and self.state == 6)
        self.x_we <<= self.instr.value() in (0b100, 0b101) and self.state == 6

        # sta/stx
        self.a_oe <<= self.instr.value() == 0b010 and self.state in (
            5,
            6,
        )
        self.x_oe <<= self.instr.value() == 0b110 and self.state in (
            5,
            6,
        )
        self.ram_we <<= (self.instr.value() in (
            0b010,
            0b110,
        ) and self.state == 6)

        # Indexing for alu(a), sta
        self.idx_en <<= self.instr.value() in (0b000, 0b001,
                                               0b010) and self.state > 3

        # jcc c=0 / jnz z=0
        self.pc_we <<= (
            (self.instr.value() == 0b011 and self.carry.value() == 0) or
            (self.instr.value() == 0b111
             and self.z.value() == 0)) and self.state == 5
        # jcc c=1 / jnz z=1
        self.a_cc <<= (
            (self.instr.value() == 0b011 and self.carry.value() != 0) or
            (self.instr.value() == 0b111
             and self.z.value() != 0)) and self.state == 5
Пример #7
0
class Decoder(Component):
    def __init__(self):
        super().__init__("decoder")
        self.clk = NotifySignal(self, "clk", 1)
        self.addr = Signal(self, "addr", 5)
        self.data = Signal(self, "data", 8)
        self.we = Signal(self, "we", 1)
        self.oe = Signal(self, "oe", 1)
        self.acc = 0
        self.x = 0
        self.adreg = 0
        self.pc = 0
        self.states = 0

    def reset(self):
        self.addr <<= 0
        self.data <<= None
        self.oe <<= 1
        self.we <<= 0

    def update(self, signal):
        if self.clk.had_edge(0, 1):
            if self.states == 0b0000:
                self.pc = self.adreg + 1
                self.adreg = self.data.value()
            else:
                self.adreg = self.pc

                # ALU / Data Path
                if self.states == 0b0110:
                    # print('  add a {} + {}'.format(self.acc, self.data.value()))
                    self.acc = ((self.acc & 0xFF) + self.data.value()) & 0x1FF
                    # print('    = {}'.format(self.acc))
                elif self.states == 0b0111:
                    # print('  nor a {} + {}'.format(self.acc, self.data.value()))
                    carry = self.acc & 0b100000000
                    value = self.acc & 0xFF
                    nor = (~(value | self.data.value())) & 0xFF
                    self.acc = carry | nor
                    # print('    = {}'.format(self.acc))
                elif self.states == 0b0010:
                    # print('  add x {} + {}'.format(self.x, self.data.value()))
                    self.x = ((self.x & 0xFF) + self.data.value()) & 0x1FF
                elif self.states == 0b0011:
                    # print('  nor x {} + {}'.format(self.x, self.data.value()))
                    carry = self.x & 0b100000000
                    value = self.x & 0xFF
                    nor = (~(value | self.data.value())) & 0xFF
                    self.x = carry | nor
                elif self.states == 0b1101:
                    # Clear carry
                    # print('  j not taken')
                    self.acc = self.acc & 0xFF
                elif self.states == 0b0101:
                    # print('  sta')
                    pass
                elif self.states == 0b0001:
                    # print('  stx')
                    pass
                else:
                    print("  unknown state")

            # State machine
            if self.states != 0b0000:
                self.states = 0b0000
            elif (self.data.value() & 0b01100000) == 0b01100000:
                # print('  maybe jump {} {}'.format(self.acc >> 8, self.acc))
                if not (self.data.value() & 0b10000000) and (self.acc
                                                             & 0b100000000):
                    # print('  jcc not taken')
                    self.states = 0b1101
                elif (self.data.value() & 0b10000000) and (self.acc
                                                           & 0xFF) == 0:
                    # print('  jnz not taken')
                    self.states = 0b1101
                else:
                    # print('  branch taken')
                    self.states = 0b0000
            else:
                # print('  going to state for {:03b}'.format(self.data.value() >> 5))
                self.states = ~((self.data.value() >> 5) & 0b111) & 0b111
                if (not (self.data.value() >> 7)
                        and (self.data.value() & 0b01100000) != 0b01100000):
                    # print('offset by x', self.x)
                    self.adreg += self.x

        clk = self.clk.value()
        self.addr <<= self.adreg & 0x1F
        if self.states == 0b0101:
            self.data <<= self.acc & 0xFF
        elif self.states == 0b0001:
            self.data <<= self.x & 0xFF
        else:
            self.data <<= None
        self.oe <<= (0 if (clk == 1 or self.states in (
            0b0001,
            0b0101,
            0b1101,
        )) else 1)
        self.we <<= (0 if (clk == 1 or self.states not in (
            0b0001,
            0b0101,
        )) else 1)
Пример #8
0
class Logic(Component):
    def __init__(self):
        super().__init__("logic")
        self.a = NotifySignal(self, "a", 8)
        self.b = NotifySignal(self, "b", 8)
        self.fn = NotifySignal(self, "fn", 4)
        self.out = Signal(self, "out", 8)
        self.fi = NotifySignal(self, "fi", 4)
        self.fo = Signal(self, "fo", 4)
        self.oe = NotifySignal(self, "oe", 1)

        # c = carry
        # z = zero
        # n = negative
        # v = overflow

    def update(self, signal):
        if self.oe.value():
            a = self.a.value()
            b = self.b.value()
            flags = self.fi.value()
            c = (flags >> 3) & 1
            v = (flags >> 2) & 1
            n = (flags >> 1) & 1
            z = (flags >> 0) & 1
            o = 0
            of = None
            calc_flags = True
            fn = self.fn.value()

            if fn == 0:
                # not, cznv
                o = ~a
            elif fn == 1:
                # xor, znv
                o = a ^ b
            elif fn == 2:
                # or, znv
                o = a | b
            elif fn == 3:
                # and, znv
                o = a & b
            elif fn == 4:
                # add, cznv
                o = a + b  # + c
            elif fn == 5:
                # sub, cznv
                o = a - b  # - c
            elif fn == 6:
                # cmp, cznv
                # a - b - c?
                o = a
                of = a - b
            elif fn == 7:
                # shl, cznv
                o = a << 1
            elif fn == 8:
                # shr, cznv
                o = a >> 1
            elif fn == 9:
                # inc, znv
                o = a + 1
            elif fn == 10:
                # dec, znv
                o = a - 1
            elif fn == 11:
                # neg, cznv
                o = -a
            elif fn == 12:
                # clf, cznv
                o = a
                c = 0
                z = 0
                n = 0
                v = 0
                calc_flags = False
            elif fn == 13:
                # inv, cvnz
                o = a
                c = 1 - c
                z = 1 - z
                n = 1 - n
                v = 1 - v
                calc_flags = False
            elif fn == 14:
                # rol, c=a[7], znv
                o = (a << 1) | c
            elif fn == 15:
                # ror, c=a[0], znv
                o = (a >> 1) | (c << 7)

            if calc_flags:
                if of is None:
                    of = o
                c = of > 0xFF
                z = of == 0
                v = 0  # TODO: signed
                n = of < 0  # TODO: signed

            self.out <<= o & 0xFF
            self.fo <<= (c << 3) | (v << 2) | (n << 1) | (z << 0)
        else:
            self.out <<= None
            self.fo <<= None
Пример #9
0
class Decoder(Component):
    def __init__(self):
        super().__init__("decoder")
        self.instr = Signal(self, "instr", 8)
        self.flags = Signal(self, "flags", 4)
        self.clk = NotifySignal(self, "clk", 2)

        self.al_ie = Signal(self, "al_ie", 1)
        self.ah_ie = Signal(self, "ah_ie", 1)
        self.bl_ie = Signal(self, "bl_ie", 1)
        self.bh_ie = Signal(self, "bh_ie", 1)
        self.cl_ie = Signal(self, "cl_ie", 1)
        self.ch_ie = Signal(self, "ch_ie", 1)
        self.dl_ie = Signal(self, "dl_ie", 1)
        self.dh_ie = Signal(self, "dh_ie", 1)
        self.e_ie = Signal(self, "e_ie", 1)
        self.f_ie = Signal(self, "f_ie", 1)
        self.g_ie = Signal(self, "g_ie", 1)
        self.h_ie = Signal(self, "h_ie", 1)
        self.t_ie = Signal(self, "t_ie", 1)

        self.a_oe = Signal(self, "a_oe", 1)
        self.b_oe = Signal(self, "b_oe", 1)
        self.c_oe = Signal(self, "c_oe", 1)
        self.d_oe = Signal(self, "d_oe", 1)
        self.e_oe = Signal(self, "e_oe", 1)
        self.f_oe = Signal(self, "f_oe", 1)
        self.g_oe = Signal(self, "g_oe", 1)
        self.h_oe = Signal(self, "h_oe", 1)

        self.t_oe = Signal(self, "t_oe", 1)

        self.pc_inc = Signal(self, "pc_inc", 1)
        self.pc_ie = Signal(self, "pc_ie", 1)

        self.ir_ie = Signal(self, "ir_ie", 1)
        self.ir_oe = Signal(self, "ir_oe", 1)

        self.alu_fn = Signal(self, "alu_fn", 4)
        self.alu_oe = Signal(self, "alu_oe", 1)

        self.sel_cd = Signal(self, "sel_cd", 1)
        self.sel_gh = Signal(self, "sel_gh", 1)

        self.mem_ie = Signal(self, "mem_ie", 1)
        self.mem_oe = Signal(self, "mem_oe", 1)

        self.flags_ie = Signal(self, "flags_ie", 1)
        self.flags_tmp_ie = Signal(self, "flags_tmp_ie", 1)

    def reset(self):
        self.pc_inc <<= 0

    def update(self, signal):
        clk = self.clk.value()
        m1 = clk <= 1
        m2 = clk == 1
        m3 = clk >= 2
        m4 = clk == 3
        # print('m1' if m1 else '', 'm2' if m2 else '', 'm3' if m3 else '', 'm4' if m4 else '')

        self.ir_ie <<= m1
        self.flags_ie <<= m1

        instr = self.instr.value()

        flags = self.flags.value()
        c = (flags >> 3) & 1
        v = (flags >> 2) & 1
        n = (flags >> 1) & 1
        z = (flags >> 0) & 1

        b7 = (instr >> 7) & 1
        b6 = (instr >> 6) & 1
        b5 = (instr >> 5) & 1
        b4 = (instr >> 4) & 1

        a_ie = 0
        b_ie = 0
        c_ie = 0
        d_ie = 0
        e_ie = 0
        f_ie = 0
        g_ie = 0
        h_ie = 0

        a_oe = 0
        b_oe = 0
        c_oe = 0
        d_oe = 0
        e_oe = 0
        f_oe = 0
        g_oe = 0
        h_oe = 0

        t_ie = 0
        t_oe = 0

        flags_tmp_ie = 0

        sel_cd = 0
        sel_gh = 0

        # IMM
        is_imm = not b7
        is_imm_high = (instr >> 4) & 1
        imm_dest = (instr >> 5) & 3
        self.ir_oe <<= m3 & is_imm

        # MOV
        is_mov = b7 and not b6
        mov_src = (instr >> 3) & 7
        mov_dst = instr & 7
        mov_oe = m1 & is_mov
        mov_ie = m4 & is_mov

        a_oe |= mov_oe & (mov_src == 0)
        b_oe |= mov_oe & (mov_src == 1)
        c_oe |= mov_oe & (mov_src == 2)
        d_oe |= mov_oe & (mov_src == 3)
        e_oe |= mov_oe & (mov_src == 4)
        f_oe |= mov_oe & (mov_src == 5)
        g_oe |= mov_oe & (mov_src == 6)
        h_oe |= mov_oe & (mov_src == 7)

        a_ie |= mov_ie & (mov_dst == 0)
        b_ie |= mov_ie & (mov_dst == 1)
        c_ie |= mov_ie & (mov_dst == 2)
        d_ie |= mov_ie & (mov_dst == 3)
        e_ie |= mov_ie & (mov_dst == 4)
        f_ie |= mov_ie & (mov_dst == 5)
        g_ie |= mov_ie & (mov_dst == 6)
        h_ie |= mov_ie & (mov_dst == 7)

        t_ie |= m2 & is_mov
        t_oe |= m3 & is_mov

        # ALU
        is_alu = b7 and b6 and not b5
        self.alu_fn <<= (instr >> 1) & 0xF
        self.alu_oe <<= m1 & is_alu
        t_ie |= m2 & is_alu
        t_oe |= m3 & is_alu
        a_ie |= m4 & is_alu & ~(instr & 1)
        c_ie |= m4 & is_alu & (instr & 1)
        flags_tmp_ie |= m2 & is_alu

        # MEM
        is_mem = b7 and b6 and b5 and not b4
        is_mem_read = is_mem & ~((instr >> 1) & 1)
        is_mem_write = is_mem & ((instr >> 1) & 1)
        sel_cd |= is_mem & ~(instr & 1)
        sel_gh |= is_mem & (instr & 1)
        mem_reg = (instr >> 2) & 3
        mem_reg_oe = m1 & is_mem_write
        mem_reg_ie = m4 & is_mem_read

        a_oe |= mem_reg_oe & (mem_reg == 0)
        b_oe |= mem_reg_oe & (mem_reg == 1)
        e_oe |= mem_reg_oe & (mem_reg == 2)
        f_oe |= mem_reg_oe & (mem_reg == 3)
        a_ie |= mem_reg_ie & (mem_reg == 0)
        b_ie |= mem_reg_ie & (mem_reg == 1)
        e_ie |= mem_reg_ie & (mem_reg == 2)
        f_ie |= mem_reg_ie & (mem_reg == 3)

        t_ie |= m2 & is_mem
        t_oe |= m3 & is_mem

        self.mem_ie <<= m4 & is_mem_write
        self.mem_oe <<= m1 & is_mem_read

        # JMP
        is_jmp = b7 and b6 and b5 and b4
        # jmp, jz, jn, jls, jc, jo
        jmp_type = instr & 7
        do_jmp = is_jmp & (
            (jmp_type == 0)
            | (jmp_type == 1 and z == 1)
            | (jmp_type == 2 and n == 1)
            | (jmp_type == 3 and (n ^ v) == 1)
            | (jmp_type == 4 and c == 1)
            | (jmp_type == 5 and v == 1)
        )
        self.pc_inc <<= m4 & ~do_jmp  # Increment if not jump
        self.pc_ie <<= m4 & do_jmp  # Load PC if jump
        sel_cd |= m3 & do_jmp & ~((instr >> 3) & 1)
        sel_gh |= m3 & do_jmp & ((instr >> 3) & 1)

        # Set ie/oe lines.
        imm_ie_l = m4 & is_imm & ~is_imm_high
        imm_ie_h = m4 & is_imm & is_imm_high
        self.al_ie <<= a_ie | (imm_ie_l & (imm_dest == 0))
        self.ah_ie <<= a_ie | (imm_ie_h & (imm_dest == 0))
        self.bl_ie <<= b_ie | (imm_ie_l & (imm_dest == 1))
        self.bh_ie <<= b_ie | (imm_ie_h & (imm_dest == 1))
        self.cl_ie <<= c_ie | (imm_ie_l & (imm_dest == 2))
        self.ch_ie <<= c_ie | (imm_ie_h & (imm_dest == 2))
        self.dl_ie <<= d_ie | (imm_ie_l & (imm_dest == 3))
        self.dh_ie <<= d_ie | (imm_ie_h & (imm_dest == 3))
        self.e_ie <<= e_ie
        self.f_ie <<= f_ie
        self.g_ie <<= g_ie
        self.h_ie <<= h_ie

        self.a_oe <<= a_oe
        self.b_oe <<= b_oe
        self.c_oe <<= c_oe
        self.d_oe <<= d_oe
        self.e_oe <<= e_oe
        self.f_oe <<= f_oe
        self.g_oe <<= g_oe
        self.h_oe <<= h_oe

        self.t_ie <<= t_ie
        self.t_oe <<= t_oe

        self.flags_tmp_ie <<= flags_tmp_ie

        self.sel_cd <<= sel_cd
        self.sel_gh <<= sel_gh
Пример #10
0
class Decoder(Component):
    MASK_OP = 0b011
    MASK_REG = 0b100
    OP_NOR = 0b000
    OP_ADD = 0b001
    OP_ST = 0b010
    OP_J = 0b011
    REG_A = 0b000
    REG_X = 0b100

    def __init__(self):
        super().__init__("decoder")
        self.clk = NotifySignal(self, "clk", 1)
        self.addr = Signal(self, "addr", 13)
        self.data = Signal(self, "data", 8)
        self.we = Signal(self, "we", 1)
        self.oe = Signal(self, "oe", 1)
        self.acc = 0
        self.x = 0
        self.adreg = 0
        self.hi5 = 0
        self.pc = 0
        self.state = 0
        self.op = 0

    def reset(self):
        self.addr <<= 0
        self.data <<= None
        self.oe <<= 1
        self.we <<= 0

    def update(self, signal):
        if self.clk.had_edge(0, 1):
            # print('clock {}'.format(self.state))
            if self.state == 0:
                self.pc = self.adreg + 2
                self.adreg = self.adreg + 1
                self.op = (self.data.value() >> 5) & 0b111
                self.hi5 = self.data.value() & 0x1F
            elif self.state == 1:
                self.adreg = (self.hi5 << 8) | self.data.value()
            elif self.state == 2:
                self.adreg = self.pc

                # ALU / Data Path
                if self.op == Decoder.REG_A | Decoder.OP_ADD:
                    # print('  add a {} + {}'.format(self.acc, self.data.value()))
                    self.acc = ((self.acc & 0xFF) + self.data.value()) & 0x1FF
                    # print('    = {}'.format(self.acc))
                elif self.op == Decoder.REG_A | Decoder.OP_NOR:
                    # print('  nor a {} + {}'.format(self.acc, self.data.value()))
                    carry = self.acc & 0b100000000
                    value = self.acc & 0xFF
                    nor = (~(value | self.data.value())) & 0xFF
                    self.acc = carry | nor
                    # print('    = {}'.format(self.acc))
                elif self.op == Decoder.REG_X | Decoder.OP_ADD:
                    # print('  add x {} + {}'.format(self.x, self.data.value()))
                    self.x = ((self.x & 0xFF) + self.data.value()) & 0x1FF
                elif self.op == Decoder.REG_X | Decoder.OP_NOR:
                    # print('  nor x {} + {}'.format(self.x, self.data.value()))
                    carry = self.x & 0b100000000
                    value = self.x & 0xFF
                    nor = (~(value | self.data.value())) & 0xFF
                    self.x = carry | nor
                elif (self.op & Decoder.MASK_OP) == Decoder.OP_J:
                    # Clear carry on all non-taken jumps.
                    # print('  j not taken')
                    self.acc = self.acc & 0xFF
                elif (self.op & Decoder.MASK_OP) == Decoder.OP_ST:
                    # print('  sta / stx')
                    pass
                else:
                    print("  unknown op")
            else:
                print("unknown state")

            # State machine
            if self.state == 0:
                # print('get next byte')
                self.state = 1
            elif self.state == 2:
                self.state = 0
            elif self.state == 1:
                if (self.op & Decoder.MASK_OP) == Decoder.OP_J:
                    # print('  maybe jump {} {}'.format(self.acc >> 8, self.acc))
                    if self.op & Decoder.MASK_REG == Decoder.REG_A and (
                            self.acc & 0b100000000):
                        # print('  jcc not taken')
                        self.state = 2
                    elif (self.op & Decoder.MASK_REG == Decoder.REG_X
                          and (self.acc & 0xFF) == 0):
                        # print('  jnz not taken')
                        self.state = 2
                    else:
                        # print('  branch taken')
                        self.state = 0
                else:
                    self.state = 2
                    # print('  going to state={} op={:03b}'.format(self.state, self.op))
                    if self.op & Decoder.MASK_REG == 0:
                        # print('offset by x', self.x)
                        self.adreg += self.x
            else:
                print("unknown state")

        clk = self.clk.value()
        # print('addr: {:04x}'.format(self.adreg & 0x1fff))
        self.addr <<= self.adreg & 0x1FFF

        if self.state == 2 and self.op == Decoder.REG_A | Decoder.OP_ST:
            self.data <<= self.acc & 0xFF
        elif self.state == 2 and self.op == Decoder.REG_X | Decoder.OP_ST:
            self.data <<= self.x & 0xFF
        else:
            self.data <<= None

        if clk == 1:
            self.oe <<= 0
            self.we <<= 0
        else:
            if self.state == 2 and (self.op
                                    & Decoder.MASK_OP) == Decoder.OP_ST:
                self.oe <<= 0
            else:
                self.oe <<= 1

            if self.state == 2 and (self.op
                                    & Decoder.MASK_OP) == Decoder.OP_ST:
                self.we <<= 1
            else:
                self.we <<= 0