예제 #1
0
파일: p3.py 프로젝트: beauxq/be8bbbce
def p(computer: Computer, a: Assembler):
    """ count by 3 """
    computer.ram.memory[0] = a.m(ASM.LDI, 3)
    computer.ram.memory[1] = a.m(ASM.STA, 15)
    computer.ram.memory[2] = a.m(ASM.LDI, 0)
    computer.ram.memory[3] = a.m(ASM.ADD, 15)
    computer.ram.memory[4] = a.m(ASM.OUT, 0)
    computer.ram.memory[5] = a.m(ASM.JMP, 3)
예제 #2
0
def p(computer: Computer, a: Assembler):
    """ add 28 + 14 """
    computer.ram.memory[0] = a.m(ASM.LDA, 14)
    computer.ram.memory[1] = a.m(ASM.ADD, 15)
    computer.ram.memory[2] = a.m(ASM.OUT, 0)
    computer.ram.memory[3] = a.m(ASM.HLT, 0)
    computer.ram.memory[14] = 28
    computer.ram.memory[15] = 14
예제 #3
0
def p(computer: Computer, a: Assembler):
    """ bit shift left """
    computer.ram.memory[0] = a.m(ASM.LDI, 1)
    computer.ram.memory[1] = a.m(ASM.STA, 15)
    computer.ram.memory[2] = a.m(ASM.LDA, 15)
    computer.ram.memory[3] = a.m(ASM.ADD, 15)
    computer.ram.memory[4] = a.m(ASM.STA, 15)
    computer.ram.memory[5] = a.m(ASM.JC, 0)
    computer.ram.memory[6] = a.m(ASM.JMP, 2)
예제 #4
0
파일: p2.py 프로젝트: beauxq/be8bbbce
def p(computer: Computer, a: Assembler):
    """ 5 + 6 - 7 """
    computer.ram.memory[0] = a.m(ASM.LDA, 15)
    computer.ram.memory[1] = a.m(ASM.ADD, 14)
    computer.ram.memory[2] = a.m(ASM.SUB, 13)
    computer.ram.memory[3] = a.m(ASM.OUT, 0)
    computer.ram.memory[4] = a.m(ASM.HLT, 0)
    computer.ram.memory[13] = 7
    computer.ram.memory[14] = 6
    computer.ram.memory[15] = 5
예제 #5
0
def p(computer: Computer, a: Assembler):
    """ bounce between signed ints -127 and 127 - remember to flip the 2s complement switch """
    computer.ram.memory[0] = a.m(ASM.LDA, 14)
    computer.ram.memory[1] = a.m(ASM.OUT, 0)
    computer.ram.memory[2] = a.m(ASM.ADD, 15)
    computer.ram.memory[3] = a.m(ASM.STA, 14)
    computer.ram.memory[4] = a.m(ASM.SUB, 13)
    computer.ram.memory[5] = a.m(ASM.JZ, 7)
    computer.ram.memory[6] = a.m(ASM.JMP, 0)
    computer.ram.memory[7] = a.m(ASM.SUB, 15)
    computer.ram.memory[8] = a.m(ASM.STA, 15)
    computer.ram.memory[9] = a.m(ASM.LDA, 14)
    computer.ram.memory[10] = a.m(ASM.ADD, 15)
    computer.ram.memory[11] = a.m(ASM.STA, 14)
    computer.ram.memory[12] = a.m(ASM.JMP, 0)
    computer.ram.memory[13] = 128  # const
    computer.ram.memory[14] = 0  # number counted
    computer.ram.memory[15] = 1  # step size
예제 #6
0
def p(computer: Computer, a: Assembler):
    """ Ben Eater's fibonacci """
    computer.ram.memory[0] = a.m(ASM.LDI, 1)
    computer.ram.memory[1] = a.m(ASM.STA, 14)
    computer.ram.memory[2] = a.m(ASM.LDI, 0)
    computer.ram.memory[3] = a.m(ASM.OUT, 0)
    computer.ram.memory[4] = a.m(ASM.ADD, 14)
    computer.ram.memory[5] = a.m(ASM.STA, 15)
    computer.ram.memory[6] = a.m(ASM.LDA, 14)
    computer.ram.memory[7] = a.m(ASM.STA, 13)
    computer.ram.memory[8] = a.m(ASM.LDA, 15)
    computer.ram.memory[9] = a.m(ASM.STA, 14)
    computer.ram.memory[10] = a.m(ASM.LDA, 13)
    computer.ram.memory[11] = a.m(ASM.JC, 0)
    computer.ram.memory[12] = a.m(ASM.JMP, 3)
예제 #7
0
def p(computer: Computer, a: Assembler):
    """ jump indirect """
    computer.ram.memory[0] = a.m(ASM.LDI, 3)
    computer.ram.memory[1] = a.m(ASM.STA, 15)
    computer.ram.memory[2] = a.m(ASM.JMP, 10)
    computer.ram.memory[3] = a.m(ASM.LDI, 6)
    computer.ram.memory[4] = a.m(ASM.STA, 15)
    computer.ram.memory[5] = a.m(ASM.JMP, 10)
    computer.ram.memory[6] = a.m(ASM.LDI, 9)
    computer.ram.memory[7] = a.m(ASM.STA, 15)
    computer.ram.memory[8] = a.m(ASM.JMP, 10)
    computer.ram.memory[9] = a.m(ASM.HLT, 0)
    computer.ram.memory[10] = a.m(ASM.LDA, 15)
    computer.ram.memory[11] = a.m(ASM.OUT, 0)
    computer.ram.memory[12] = a.m(ASM.JI, 15)
예제 #8
0
def p(computer: Computer, a: Assembler):
    """ load and store indirect (1 13 1) """
    computer.ram.memory[0] = a.m(ASM.LIN, 13)
    computer.ram.memory[1] = a.m(ASM.OUT, 0)  # 1
    computer.ram.memory[2] = a.m(ASM.LDA, 13)
    computer.ram.memory[3] = a.m(ASM.ADD, 14)
    computer.ram.memory[4] = a.m(ASM.SIN, 15)
    computer.ram.memory[5] = a.m(ASM.LIN, 13)
    computer.ram.memory[6] = a.m(ASM.OUT, 0)  # 13
    computer.ram.memory[7] = a.m(ASM.LDA, 13)
    computer.ram.memory[8] = a.m(ASM.SUB, 14)
    computer.ram.memory[9] = a.m(ASM.STA, 13)
    computer.ram.memory[10] = a.m(ASM.LIN, 13)
    computer.ram.memory[11] = a.m(ASM.OUT, 0)  # 1
    computer.ram.memory[12] = a.m(ASM.HLT, 0)
    computer.ram.memory[13] = 14
    computer.ram.memory[14] = 1
    computer.ram.memory[15] = 13
예제 #9
0
파일: negdivid.py 프로젝트: beauxq/be8bbbce
def p(computer: Computer, a: Assembler):
    """ use divide subroutine to test negative division """

    computer.ram.memory[0] = a.m(ASM.LDA, 15)
    computer.ram.memory[1] = a.m(ASM.STA, 2250)  # a operand
    computer.ram.memory[2] = a.m(ASM.LDI, 2)
    computer.ram.memory[3] = a.m(ASM.STA, 2251)  # b operand
    computer.ram.memory[4] = a.m(ASM.LDI, 7)
    computer.ram.memory[5] = a.m(ASM.STA, 2252)  # return program counter
    computer.ram.memory[6] = a.m(ASM.JMP, 2200)  # divide subroutine
    computer.ram.memory[7] = a.m(ASM.LDA, 2253)  # result
    computer.ram.memory[8] = a.m(ASM.OUT, 0)
    computer.ram.memory[9] = a.m(ASM.HLT, 0)

    computer.ram.memory[15] = 0b1111111111110111  # -9
예제 #10
0
def p(computer: Computer, a: Assembler):
    """ floored sqrt: sqrt(50) """
    computer.ram.memory[0] = a.m(ASM.LDA, 14)
    computer.ram.memory[1] = a.m(ASM.ADD, 13)
    computer.ram.memory[2] = a.m(ASM.STA, 14)
    computer.ram.memory[3] = a.m(ASM.LDA, 13)
    computer.ram.memory[4] = a.m(ASM.SUB, 14)
    computer.ram.memory[5] = a.m(ASM.SUB, 14)
    computer.ram.memory[6] = a.m(ASM.ADD, 15)
    computer.ram.memory[7] = a.m(ASM.STA, 15)
    computer.ram.memory[8] = a.m(ASM.JC, 0)
    computer.ram.memory[9] = a.m(ASM.LDA, 14)
    computer.ram.memory[10] = a.m(ASM.SUB, 13)
    computer.ram.memory[11] = a.m(ASM.OUT, 0)
    computer.ram.memory[12] = a.m(ASM.HLT, 0)
    computer.ram.memory[13] = 1  # const
    computer.ram.memory[14] = 0  # result
    computer.ram.memory[15] = 50  # input
예제 #11
0
파일: bern32.py 프로젝트: beauxq/be8bbbce
def main():
    a = Assembler(ADDRESS_LENGTH)

    print("initializing computer...")
    computer = Computer(ADDRESS_LENGTH, True)

    print("programming computer...")
    p1(computer, a)
    p2(computer, a)
    p4(computer, a)
    p5(computer, a)
    p6(computer, a)
    bern(computer, a)

    computer.ram.memory[267] = a.m(ASM.JMP, 4)
    # reset instead of halt to compute next

    print("running")
    computer.clock.go()
예제 #12
0
파일: divide.py 프로젝트: beauxq/be8bbbce
def p(computer: Computer, a: Assembler):
    """ integer division:  42 / 6 """
    computer.ram.memory[0] = a.m(ASM.LDA, 14)
    computer.ram.memory[1] = a.m(ASM.SUB, 15)
    computer.ram.memory[2] = a.m(ASM.JC, 6)  # if subtraction didn't go below 0
    computer.ram.memory[3] = a.m(ASM.LDA, 13)
    computer.ram.memory[4] = a.m(ASM.OUT, 0)
    computer.ram.memory[5] = a.m(ASM.HLT, 0)
    computer.ram.memory[6] = a.m(ASM.STA, 14)
    computer.ram.memory[7] = a.m(ASM.LDA, 13)
    computer.ram.memory[8] = a.m(ASM.ADD, 12)
    computer.ram.memory[9] = a.m(ASM.STA, 13)
    computer.ram.memory[10] = a.m(ASM.JMP, 0)
    computer.ram.memory[11] = a.m(ASM.NOP, 0)
    computer.ram.memory[12] = 1  # const
    computer.ram.memory[13] = 0  # count subtractions
    computer.ram.memory[14] = 42  # x = 42
    computer.ram.memory[15] = 6  # y = 6
예제 #13
0
def p(computer: Computer, a: Assembler):
    """ Ben Eater's multiplication """
    computer.ram.memory[0] = a.m(ASM.LDA, 14)
    computer.ram.memory[1] = a.m(ASM.SUB, 12)
    computer.ram.memory[2] = a.m(ASM.JC, 6)
    computer.ram.memory[3] = a.m(ASM.LDA, 13)
    computer.ram.memory[4] = a.m(ASM.OUT, 0)
    computer.ram.memory[5] = a.m(ASM.HLT, 0)
    computer.ram.memory[6] = a.m(ASM.STA, 14)
    computer.ram.memory[7] = a.m(ASM.LDA, 13)
    computer.ram.memory[8] = a.m(ASM.ADD, 15)
    computer.ram.memory[9] = a.m(ASM.STA, 13)
    computer.ram.memory[10] = a.m(ASM.JMP, 0)
    computer.ram.memory[11] = a.m(ASM.NOP, 0)
    computer.ram.memory[12] = 1
    computer.ram.memory[13] = 0  # product = 0
    computer.ram.memory[14] = 7  # x = 7
    computer.ram.memory[15] = 6  # y = 6
예제 #14
0
def p(computer: Computer, a: Assembler):
    """ pseudo- bit shift right """
    computer.ram.memory[0] = a.m(ASM.LDA, 9)
    computer.ram.memory[1] = a.m(ASM.LDA, 10)
    computer.ram.memory[2] = a.m(ASM.LDA, 11)
    computer.ram.memory[3] = a.m(ASM.LDA, 12)
    computer.ram.memory[4] = a.m(ASM.LDI, 8)
    computer.ram.memory[5] = a.m(ASM.LDI, 4)
    computer.ram.memory[6] = a.m(ASM.LDI, 2)
    computer.ram.memory[7] = a.m(ASM.LDI, 1)
    computer.ram.memory[8] = a.m(ASM.JMP, 0)
    computer.ram.memory[9] = 128
    computer.ram.memory[10] = 64
    computer.ram.memory[11] = 32
    computer.ram.memory[12] = 16
예제 #15
0
def p(computer: Computer, a: Assembler):
    """ add fractions subroutine at 2100 """

    # global utility constants
    bit_count = computer.bit_count
    computer.ram.memory[4000] = 1 << (bit_count - 1)  # min signed
    computer.ram.memory[4001] = 1
    computer.ram.memory[4002] = (2**bit_count) - 1  # -1 in two's complement

    add_fractions_subroutine = [
        a.m(ASM.LDA, 2140),
        a.m(ASM.STA, 2147),
        a.m(ASM.LDA, 2142),
        a.m(ASM.STA, 2145),
        a.m(ASM.LDA, 2141),
        a.m(ASM.STA, 2148),
        a.m(ASM.LDA, 2143),
        a.m(ASM.STA, 2144),
        a.m(ASM.LDA, 2148),  # address 2108
        a.m(ASM.SUB, 2144),
        a.m(ASM.JZ, 2127),
        a.m(ASM.ADD, 4000),
        a.m(ASM.JC, 2120),
        a.m(ASM.LDA, 2144),
        a.m(ASM.ADD, 2143),
        a.m(ASM.STA, 2144),
        a.m(ASM.LDA, 2145),
        a.m(ASM.ADD, 2142),
        a.m(ASM.STA, 2145),
        a.m(ASM.JMP, 2108),
        a.m(ASM.LDA, 2148),  # address 2120
        a.m(ASM.ADD, 2141),
        a.m(ASM.STA, 2148),
        a.m(ASM.LDA, 2147),
        a.m(ASM.ADD, 2140),
        a.m(ASM.STA, 2147),
        a.m(ASM.JMP, 2108),
        a.m(ASM.LDA, 2147),  # address 2127
        a.m(ASM.ADD, 2145),
        a.m(ASM.STA, 2147),
        a.m(ASM.JI, 2146)
    ]
    """
    parameters:
    2140  an  operand a numerator
    2141  ad  operand a denominator
    2142  bn  operand b numerator
    2143  bd  operand b denominator
    2146  pc return location

    working variables:
    2144  blcd
    2145  bnm

    result locations:
    2147  anm   result numerator
    2148  alcd  result denominator
    """

    address = 2100
    for instruction in add_fractions_subroutine:
        computer.ram.memory[address] = instruction
        address += 1

    # use the add fractions subroutine
    computer.ram.memory[0] = a.m(ASM.LDI, 1)
    computer.ram.memory[1] = a.m(ASM.STA, 2140)  # a operand numer
    computer.ram.memory[2] = a.m(ASM.LDI, 4)
    computer.ram.memory[3] = a.m(ASM.STA, 2141)  # a operand denom
    computer.ram.memory[4] = a.m(ASM.LDI, 7)
    computer.ram.memory[5] = a.m(ASM.STA, 2142)  # b operand numer
    computer.ram.memory[6] = a.m(ASM.LDI, 12)
    computer.ram.memory[7] = a.m(ASM.STA, 2143)  # b operand denom
    computer.ram.memory[8] = a.m(ASM.LDI, 11)
    computer.ram.memory[9] = a.m(ASM.STA, 2146)  # return program counter
    computer.ram.memory[10] = a.m(ASM.JMP, 2100)  # add fractions subroutine
    computer.ram.memory[11] = a.m(ASM.LDA, 2147)  # result numer
    computer.ram.memory[12] = a.m(ASM.OUT, 0)
    computer.ram.memory[13] = a.m(ASM.LDA, 2148)  # result denom
    computer.ram.memory[14] = a.m(ASM.OUT, 0)
    computer.ram.memory[15] = a.m(ASM.HLT, 0)
예제 #16
0
def p(computer: Computer, a: Assembler):
    """ divide subroutine at 2200 - requires multiply at 2000 """

    # global utility constants
    bit_count = computer.bit_count
    computer.ram.memory[4000] = 1 << (bit_count - 1)  # min signed
    computer.ram.memory[4001] = 1
    computer.ram.memory[4002] = (2**bit_count) - 1  # -1 in two's complement

    divide_subroutine = [
        a.m(ASM.LDI, 1),
        a.m(ASM.STA, 2254),
        a.m(ASM.LDA, 2250),
        a.m(ASM.ADD, 4000),
        a.m(ASM.JC, 2206),
        a.m(ASM.JMP, 2211),
        a.m(ASM.LDA, 4002),  # address 2206
        a.m(ASM.STA, 2254),
        a.m(ASM.LDI, 0),
        a.m(ASM.SUB, 2250),
        a.m(ASM.STA, 2250),
        a.m(ASM.LDI, 0),  # address 2211
        a.m(ASM.STA, 2255),
        a.m(ASM.LDA, 2250),  # address 2213
        a.m(ASM.SUB, 2251),
        a.m(ASM.ADD, 4000),
        a.m(ASM.JC, 2224),
        a.m(ASM.LDA, 2250),
        a.m(ASM.SUB, 2251),
        a.m(ASM.STA, 2250),
        a.m(ASM.LDA, 2255),
        a.m(ASM.ADD, 4001),
        a.m(ASM.STA, 2255),
        a.m(ASM.JMP, 2213),
        a.m(ASM.LDA, 2254),  # address 2224
        a.m(ASM.STA, 2080),
        a.m(ASM.LDA, 2255),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 2231),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 2231
        a.m(ASM.STA, 2253),
        a.m(ASM.JI, 2252)
    ]
    """
    integer division
    parameters:
    2250 a
    2251 b  must be positive - divide by 0 makes infinite loop
    2252 pcreturnlocation

    output:
    2253 result

    working variables:
    2254 a_sign
    2255 count
    """

    address = 2200
    for instruction in divide_subroutine:
        computer.ram.memory[address] = instruction
        address += 1

    # use the divide subroutine
    computer.ram.memory[0] = a.m(ASM.LDI, 1764)
    computer.ram.memory[1] = a.m(ASM.STA, 2250)  # a operand
    computer.ram.memory[2] = a.m(ASM.LDI, 42)
    computer.ram.memory[3] = a.m(ASM.STA, 2251)  # b operand
    computer.ram.memory[4] = a.m(ASM.LDI, 7)
    computer.ram.memory[5] = a.m(ASM.STA, 2252)  # return program counter
    computer.ram.memory[6] = a.m(ASM.JMP, 2200)  # divide subroutine
    computer.ram.memory[7] = a.m(ASM.LDA, 2253)  # result
    computer.ram.memory[8] = a.m(ASM.OUT, 0)
    computer.ram.memory[9] = a.m(ASM.HLT, 0)
예제 #17
0
def p(computer: Computer, a: Assembler):
    """ gcd subroutine at 2300 """

    # global utility constants
    bit_count = computer.bit_count
    computer.ram.memory[4000] = 1 << (bit_count - 1)  # min signed
    computer.ram.memory[4001] = 1
    computer.ram.memory[4002] = (2**bit_count) - 1  # -1 in two's complement

    gcd_subroutine = [
        a.m(ASM.LDA, 2350),
        a.m(ASM.SUB, 2351),
        a.m(ASM.JZ, 2313),
        a.m(ASM.ADD, 4000),
        a.m(ASM.JC, 2309),
        a.m(ASM.LDA, 2350),
        a.m(ASM.SUB, 2351),
        a.m(ASM.STA, 2350),
        a.m(ASM.JMP, 2300),
        a.m(ASM.LDA, 2351),  # address 2309
        a.m(ASM.SUB, 2350),
        a.m(ASM.STA, 2351),
        a.m(ASM.JMP, 2300),
        a.m(ASM.JI, 2352)  # address 2313
    ]
    """
    parameters:
    2350 a  must be positive
    2351 b  must be positive
    2352 pc return location

    output:
    2350 result
    """

    address = 2300
    for instruction in gcd_subroutine:
        computer.ram.memory[address] = instruction
        address += 1

    # use the gcd subroutine
    computer.ram.memory[0] = a.m(ASM.LDI, 210)
    computer.ram.memory[1] = a.m(ASM.STA, 2350)  # a operand
    computer.ram.memory[2] = a.m(ASM.LDI, 546)
    computer.ram.memory[3] = a.m(ASM.STA, 2351)  # b operand
    computer.ram.memory[4] = a.m(ASM.LDI, 7)
    computer.ram.memory[5] = a.m(ASM.STA, 2352)  # return program counter
    computer.ram.memory[6] = a.m(ASM.JMP, 2300)  # gcd subroutine
    computer.ram.memory[7] = a.m(ASM.LDA, 2350)  # result
    computer.ram.memory[8] = a.m(ASM.OUT, 0)
    computer.ram.memory[9] = a.m(ASM.HLT, 0)
예제 #18
0
def p(computer: Computer, a: Assembler):
    """ reduce fraction subroutine at 2400 - requires divide and gcd """

    # global utility constants
    bit_count = computer.bit_count
    computer.ram.memory[4000] = 1 << (bit_count - 1)  # min signed
    computer.ram.memory[4001] = 1
    computer.ram.memory[4002] = (2**bit_count) - 1  # -1 in two's complement

    reduce_subroutine = [
        a.m(ASM.LDA, 2451),
        a.m(ASM.ADD, 4000),
        a.m(ASM.JC, 2404),
        a.m(ASM.JMP, 2410),
        a.m(ASM.LDI, 0),  # address 2404
        a.m(ASM.SUB, 2450),
        a.m(ASM.STA, 2450),
        a.m(ASM.LDI, 0),
        a.m(ASM.SUB, 2451),
        a.m(ASM.STA, 2451),
        a.m(ASM.LDA, 2450),  # address 2410
        a.m(ASM.STA, 2453),
        a.m(ASM.ADD, 4000),
        a.m(ASM.JC, 2415),
        a.m(ASM.JMP, 2418),
        a.m(ASM.LDI, 0),  # address 2415
        a.m(ASM.SUB, 2453),
        a.m(ASM.STA, 2453),
        a.m(ASM.LDA, 2453),  # address 2418
        a.m(ASM.STA, 2350),
        a.m(ASM.LDA, 2451),
        a.m(ASM.STA, 2351),
        a.m(ASM.LDI, 2425),
        a.m(ASM.STA, 2352),
        a.m(ASM.JMP, 2300),
        a.m(ASM.LDA, 2350),  # address 2425
        a.m(ASM.STA, 2453),
        a.m(ASM.LDA, 2450),
        a.m(ASM.STA, 2250),
        a.m(ASM.LDA, 2453),
        a.m(ASM.STA, 2251),
        a.m(ASM.LDI, 2434),
        a.m(ASM.STA, 2252),
        a.m(ASM.JMP, 2200),
        a.m(ASM.LDA, 2253),  # address 2434
        a.m(ASM.STA, 2450),
        a.m(ASM.LDA, 2451),
        a.m(ASM.STA, 2250),
        a.m(ASM.LDA, 2453),
        a.m(ASM.STA, 2251),
        a.m(ASM.LDI, 2443),
        a.m(ASM.STA, 2252),
        a.m(ASM.JMP, 2200),
        a.m(ASM.LDA, 2253),  # address 2443
        a.m(ASM.STA, 2451),
        a.m(ASM.JI, 2452)
    ]
    """
    parameters:
    2450  n   numerator
    2451  d   denominator
    2452  pc return location

    working variables:
    2453  n_positive and divisor

    result locations:
    2450  n   result numerator
    2451  d   result denominator
    """

    address = 2400
    for instruction in reduce_subroutine:
        computer.ram.memory[address] = instruction
        address += 1

    # use the reduce subroutine
    computer.ram.memory[0] = a.m(ASM.LDI, 10)
    computer.ram.memory[1] = a.m(ASM.STA, 2450)  # n
    computer.ram.memory[2] = a.m(ASM.LDI, 12)
    computer.ram.memory[3] = a.m(ASM.STA, 2451)  # d
    computer.ram.memory[4] = a.m(ASM.LDI, 7)
    computer.ram.memory[5] = a.m(ASM.STA, 2452)  # return program counter
    computer.ram.memory[6] = a.m(ASM.JMP, 2400)  # gcd subroutine
    computer.ram.memory[7] = a.m(ASM.LDA, 2450)  # result
    computer.ram.memory[8] = a.m(ASM.OUT, 0)
    computer.ram.memory[9] = a.m(ASM.LDA, 2451)  # result
    computer.ram.memory[10] = a.m(ASM.OUT, 0)
    computer.ram.memory[11] = a.m(ASM.HLT, 0)
예제 #19
0
def p(computer: Computer, a: Assembler):
    """ multiply subroutine at 2000
    faster for big numbers
    slower for small numbers """

    # global utility constants
    bit_count = computer.bit_count
    computer.ram.memory[4000] = 1 << (bit_count - 1)  # min signed
    computer.ram.memory[4001] = 1
    computer.ram.memory[4002] = (2**bit_count) - 1  # -1 in two's complement

    multiply_subroutine = [
        a.m(ASM.LDA, 2080),
        a.m(ASM.ADD, 4000),
        a.m(ASM.JC, 2004),
        a.m(ASM.JMP, 2010),
        a.m(ASM.LDI, 0),
        a.m(ASM.SUB, 2080),
        a.m(ASM.STA, 2080),
        a.m(ASM.LDI, 0),
        a.m(ASM.SUB, 2081),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 0),
        a.m(ASM.STA, 2083),
        a.m(ASM.LDI, 0),
        a.m(ASM.ADD, 2080),
        a.m(ASM.JZ, 2076),
        a.m(ASM.LDI, 1),
        a.m(ASM.STA, 2086),
        a.m(ASM.STA, 2088),
        a.m(ASM.LDA, 2081),
        a.m(ASM.STA, 2083),
        a.m(ASM.SIN, 2084),
        a.m(ASM.LDI, 2),
        a.m(ASM.STA, 2089),
        a.m(ASM.LDA, 2080),
        a.m(ASM.SUB, 2089),
        a.m(ASM.JC, 2027),
        a.m(ASM.JMP, 2045),
        a.m(ASM.LDA, 2083),
        a.m(ASM.ADD, 2083),
        a.m(ASM.STA, 2083),
        a.m(ASM.LDA, 2088),
        a.m(ASM.ADD, 2088),
        a.m(ASM.STA, 2088),
        a.m(ASM.LDA, 2086),
        a.m(ASM.ADD, 2084),
        a.m(ASM.STA, 2087),
        a.m(ASM.LDA, 2083),
        a.m(ASM.SIN, 2087),
        a.m(ASM.LDA, 2088),
        a.m(ASM.ADD, 2088),
        a.m(ASM.STA, 2089),
        a.m(ASM.LDI, 1),
        a.m(ASM.ADD, 2086),
        a.m(ASM.STA, 2086),
        a.m(ASM.JMP, 2023),
        a.m(ASM.LDA, 2086),
        a.m(ASM.SUB, 2090),
        a.m(ASM.STA, 2086),
        a.m(ASM.ADD, 4000),
        a.m(ASM.JC, 2076),
        a.m(ASM.LDA, 2086),
        a.m(ASM.ADD, 2085),
        a.m(ASM.STA, 2087),
        a.m(ASM.LIN, 2087),
        a.m(ASM.ADD, 2088),
        a.m(ASM.STA, 2087),
        a.m(ASM.LDA, 2080),
        a.m(ASM.SUB, 2087),
        a.m(ASM.JC, 2060),
        a.m(ASM.JMP, 2072),
        a.m(ASM.LDA, 2086),
        a.m(ASM.ADD, 2084),
        a.m(ASM.STA, 2087),
        a.m(ASM.LIN, 2087),
        a.m(ASM.ADD, 2083),
        a.m(ASM.STA, 2083),
        a.m(ASM.LDA, 2086),
        a.m(ASM.ADD, 2085),
        a.m(ASM.STA, 2087),
        a.m(ASM.LIN, 2087),
        a.m(ASM.ADD, 2088),
        a.m(ASM.STA, 2088),
        a.m(ASM.LDA, 2086),
        a.m(ASM.SUB, 4001),
        a.m(ASM.STA, 2086),
        a.m(ASM.JMP, 2048),
        a.m(ASM.JI, 2082)
    ]
    """
    2080 a operand
    2081 b operand
    2082 pc return location
    2083 result

    2084 powers (pointer)
    2085 addition counts (pointer)
    2086 cache index
    2087 pointer (temp)
    2088 additions done
    2089 double
    2090 2 const

    400 powers 
    500-564 addition counts
    """

    # place those constants ^
    computer.ram.memory[2084] = 400
    computer.ram.memory[2085] = 500
    computer.ram.memory[2090] = 2

    for i in range(500, 565):
        computer.ram.memory[i] = 2**(i - 500)

    address = 2000
    for instruction in multiply_subroutine:
        computer.ram.memory[address] = instruction
        address += 1

    # use the multiply subroutine
    computer.ram.memory[0] = a.m(ASM.LDI, 7)
    computer.ram.memory[1] = a.m(ASM.STA, 2080)  # a operand
    computer.ram.memory[2] = a.m(ASM.LDI, 6)
    computer.ram.memory[3] = a.m(ASM.STA, 2081)  # b operand
    computer.ram.memory[4] = a.m(ASM.LDI, 7)
    computer.ram.memory[5] = a.m(ASM.STA, 2082)  # return program counter
    computer.ram.memory[6] = a.m(ASM.JMP, 2000)  # multiply subroutine
    computer.ram.memory[7] = a.m(ASM.LDA, 2083)  # result
    computer.ram.memory[8] = a.m(ASM.OUT, 0)
    computer.ram.memory[9] = a.m(ASM.HLT, 0)
예제 #20
0
def p(computer: Computer, a: Assembler):
    """ Ada Lovelace's Bernoulli number calculator """

    bernoulli = [
        a.m(ASM.LDI, 1),
        a.m(ASM.STA, 1010),
        a.m(ASM.LDI, 2),
        a.m(ASM.STA, 1020),
        a.m(ASM.LDI, 0),
        a.m(ASM.STA, 1070),
        a.m(ASM.STA, 1130),
        # op1 v4,v5,v6 = v2 * v3
        a.m(ASM.LDA, 1020),
        a.m(ASM.STA, 2080),
        a.m(ASM.LDA, 1030),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 14),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 14
        a.m(ASM.STA, 1040),
        a.m(ASM.STA, 1050),
        a.m(ASM.STA, 1060),
        # op2 v4 = v4 - v1
        a.m(ASM.LDA, 1040),
        a.m(ASM.SUB, 1010),
        a.m(ASM.STA, 1040),
        # op3 v5 = v5 + v1
        a.m(ASM.LDA, 1050),
        a.m(ASM.ADD, 1010),
        a.m(ASM.STA, 1050),
        # op4 v11f = v4 / v5
        a.m(ASM.STA, 1111),
        a.m(ASM.LDA, 1040),
        a.m(ASM.STA, 1110),
        # op5 v11 = v11 / v2 -> v11d = multiply(v11d, v2i)
        a.m(ASM.LDA, 1111),
        a.m(ASM.STA, 2081),  # better when a is lower number
        a.m(ASM.LDA, 1020),
        a.m(ASM.STA, 2080),
        a.m(ASM.LDI, 34),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 34
        a.m(ASM.STA, 1111),
        # op6 v13 = v13 - v11
        # v13n = v13n - v11n; v13d = v11d
        # v13n, v13d = reduce(v13n, v13d)
        # TODO: remove this reduce, there's no way this isn't already reduced
        a.m(ASM.LDA, 1130),
        a.m(ASM.SUB, 1110),
        a.m(ASM.STA, 2450),  # store in reduce parameter
        a.m(ASM.LDA, 1111),
        a.m(ASM.STA, 2451),
        a.m(ASM.LDI, 44),
        a.m(ASM.STA, 2452),
        a.m(ASM.JMP, 2400),
        a.m(ASM.LDA, 2450),  # address 44
        a.m(ASM.STA, 1130),
        a.m(ASM.LDA, 2451),
        a.m(ASM.STA, 1131),
        # op7 v10i = v3i - v1i
        a.m(ASM.LDA, 1030),
        a.m(ASM.SUB, 1010),
        a.m(ASM.STA, 1100),  # on first run, v10 is now 1
        # op8 v7i = v2i + v7i
        a.m(ASM.LDA, 1020),
        a.m(ASM.ADD, 1070),
        a.m(ASM.STA, 1070),
        # op9 v11 = v6 / v7 ~ v11n = v6i; v11d = v7i
        a.m(ASM.STA, 1111),
        a.m(ASM.LDA, 1060),
        a.m(ASM.STA, 1110),
        # op10 v12 = v20[1] * v11
        # v12n = multiply(v20n[1], v11n)
        # v12d = multiply(v20d[1], v11d)
        a.m(ASM.LDA, 1210),
        a.m(ASM.STA, 2080),
        a.m(ASM.LDA, 1110),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 64),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 64
        a.m(ASM.STA, 1120),
        a.m(ASM.LDA, 1211),
        a.m(ASM.STA, 2080),
        a.m(ASM.LDA, 1111),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 73),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 73
        a.m(ASM.STA, 1121),
        # op11 v13 = v12 + v13
        # v13n, v13d = add_f(v12n, v12d, v13n, v13d)
        # v13n, v13d = red(v13n, v13d)
        a.m(ASM.LDA, 1120),
        a.m(ASM.STA, 2140),
        a.m(ASM.LDA, 1121),
        a.m(ASM.STA, 2141),
        a.m(ASM.LDA, 1130),
        a.m(ASM.STA, 2142),
        a.m(ASM.LDA, 1131),
        a.m(ASM.STA, 2143),
        a.m(ASM.LDI, 86),
        a.m(ASM.STA, 2146),
        a.m(ASM.JMP, 2100),
        a.m(ASM.LDA, 2147),  # address 86 - from output of add
        a.m(ASM.STA, 2450),  # to input of reduce
        a.m(ASM.LDA, 2148),
        a.m(ASM.STA, 2451),
        a.m(ASM.LDI, 93),
        a.m(ASM.STA, 2452),
        a.m(ASM.JMP, 2400),
        a.m(ASM.LDA, 2450),  # address 93
        a.m(ASM.STA, 1130),
        a.m(ASM.LDA, 2451),
        a.m(ASM.STA, 1131),
        # op12 v10i = v10i - v1i
        a.m(ASM.LDA, 1100),
        a.m(ASM.SUB, 1010),
        a.m(ASM.STA, 1100),  # first run v10 is now 0
        # while v10i > 0
        # both here and before I jump back here,
        # v10 in reg A, zero flag set if 0
        a.m(ASM.JZ, 245),  # address 100
        # op13 v6i = v6i - v1i
        a.m(ASM.LDA, 1060),
        a.m(ASM.SUB, 1010),
        a.m(ASM.STA, 1060),
        # op14 v7i = v1i + v7i
        a.m(ASM.LDA, 1010),
        a.m(ASM.ADD, 1070),
        a.m(ASM.STA, 1070),
        # op15 v8 = v6 / v7
        # v8n = v6i
        # v8d = v7i
        # v8n, v8d = reduce(v8n, v8d)
        a.m(ASM.STA, 2451),  # v7 already in mem, to reduce param
        a.m(ASM.LDA, 1060),
        a.m(ASM.STA, 2450),
        a.m(ASM.LDI, 113),
        a.m(ASM.STA, 2452),
        a.m(ASM.JMP, 2400),
        a.m(ASM.LDA, 2451),  # address 113
        a.m(ASM.STA, 1081),
        a.m(ASM.LDA, 2450),
        a.m(ASM.STA, 1080),
        # op16 v11 = v8 * v11  ~  mult n; mult d; then reduce
        a.m(ASM.STA, 2080),  # v8n already in reg A
        a.m(ASM.LDA, 1110),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 123),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 123 - numer to be reduced
        a.m(ASM.STA, 2450),  # leave that there for a bit
        a.m(ASM.LDA, 1081),
        a.m(ASM.STA, 2080),
        a.m(ASM.LDA, 1111),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 132),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 132 - denom
        a.m(ASM.STA, 2451),  # to be reduced
        a.m(ASM.LDI, 137),
        a.m(ASM.STA, 2452),
        a.m(ASM.JMP, 2400),
        a.m(ASM.LDA, 2450),  # address 137
        a.m(ASM.STA, 1110),
        a.m(ASM.LDA, 2451),
        a.m(ASM.STA, 1111),
        # op17 v6i = v6i - v1i
        a.m(ASM.LDA, 1060),
        a.m(ASM.SUB, 1010),
        a.m(ASM.STA, 1060),
        # op18 v7i = v1i + v7i
        a.m(ASM.LDA, 1010),
        a.m(ASM.ADD, 1070),
        a.m(ASM.STA, 1070),
        # op19 v9 = v6i / v7i  ~  reduce then put in v9
        a.m(ASM.STA, 2451),  # v7 already in reg A
        a.m(ASM.LDA, 1060),
        a.m(ASM.STA, 2450),
        a.m(ASM.LDI, 153),
        a.m(ASM.STA, 2452),
        a.m(ASM.JMP, 2400),
        a.m(ASM.LDA, 2451),  # address 153 - denom first
        a.m(ASM.STA, 1091),
        a.m(ASM.LDA, 2450),
        a.m(ASM.STA, 1090),
        # op20 v11 = v9 * v11
        # mult n; mult d; then reduce ~ copy paste from op16
        a.m(ASM.STA, 2080),  # v9n already in reg A
        a.m(ASM.LDA, 1110),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 163),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 163 - numer to be reduced
        a.m(ASM.STA, 2450),  # leave that there for a bit
        a.m(ASM.LDA, 1091),
        a.m(ASM.STA, 2080),
        a.m(ASM.LDA, 1111),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 172),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 172 - denom
        a.m(ASM.STA, 2451),  # to be reduced
        a.m(ASM.LDI, 177),
        a.m(ASM.STA, 2452),
        a.m(ASM.JMP, 2400),
        a.m(ASM.LDA, 2450),  # address 177
        a.m(ASM.STA, 1110),
        a.m(ASM.LDA, 2451),
        a.m(ASM.STA, 1111),
        # op21 v12 = v20[v3i - v10i] * v11
        # mult(v20n[v3i - v10i], v11n); then d; then reduce
        a.m(ASM.NOP, 0),  # for safety - wiggle room for fixing mistakes
        # about to make address for v20n[v3i - v10i]
        a.m(ASM.LDA, 1030),  # v3i
        a.m(ASM.SUB, 1100),  # - v10i
        a.m(ASM.STA, 2080),
        a.m(ASM.LDI, 10),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 190),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDI, 1200),  # address 190
        a.m(ASM.ADD, 2083),  # 1200 + (v3i - v10i) * 10
        a.m(ASM.STA, 900),  # address of v20n[v3i - v10i]
        a.m(ASM.ADD, 1010),
        a.m(ASM.STA, 901),  # address of v20d[v3i - v10i]
        a.m(ASM.LIN, 900),
        a.m(ASM.STA, 2080),
        a.m(ASM.LDA, 1110),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 202),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 202 - numer to be reduced
        a.m(ASM.STA, 2450),  # leave that there for a bit
        a.m(ASM.LIN, 901),
        a.m(ASM.STA, 2080),
        a.m(ASM.LDA, 1111),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 211),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDA, 2083),  # address 211 - denom to be reduced
        a.m(ASM.STA, 2451),
        a.m(ASM.LDI, 216),
        a.m(ASM.STA, 2452),
        a.m(ASM.JMP, 2400),
        a.m(ASM.LDA, 2451),  # address 216 - d first to have n in register
        a.m(ASM.STA, 1121),
        a.m(ASM.LDA, 2450),
        a.m(ASM.STA, 1120),
        # op22 v13 = v12 + v13  ~  add fractions and reduce
        a.m(ASM.STA, 2140),  # v12n already in register
        a.m(ASM.LDA, 1121),
        a.m(ASM.STA, 2141),
        a.m(ASM.LDA, 1130),
        a.m(ASM.STA, 2142),
        a.m(ASM.LDA, 1131),
        a.m(ASM.STA, 2143),
        a.m(ASM.LDI, 230),
        a.m(ASM.STA, 2146),
        a.m(ASM.JMP, 2100),
        a.m(ASM.LDA, 2147),  # address 230
        a.m(ASM.STA, 2450),
        a.m(ASM.LDA, 2148),
        a.m(ASM.STA, 2451),
        a.m(ASM.LDI, 237),
        a.m(ASM.STA, 2452),
        a.m(ASM.JMP, 2400),
        a.m(ASM.LDA, 2450),  # address 237
        a.m(ASM.STA, 1130),
        a.m(ASM.LDA, 2451),
        a.m(ASM.STA, 1131),
        # op23 v10i = v10i - v1i
        a.m(ASM.LDA, 1100),
        a.m(ASM.SUB, 1010),  # this will set zero flag if v10 == 0
        a.m(ASM.STA, 1100),
        a.m(ASM.JMP, 100),
        # op24 v20[v3i] = v20[v3i] - v13
        # v20n[v3i] = v20n[v3i] - v13n; v20d[v3i] = v13d
        a.m(ASM.LDA, 1030),  # address 245
        a.m(ASM.STA, 2080),
        a.m(ASM.LDI, 10),
        a.m(ASM.STA, 2081),
        a.m(ASM.LDI, 252),
        a.m(ASM.STA, 2082),
        a.m(ASM.JMP, 2000),
        a.m(ASM.LDI, 1200),  # address 252
        a.m(ASM.ADD, 2083),
        a.m(ASM.STA, 900),  # v20n[v3i]
        a.m(ASM.ADD, 1010),
        a.m(ASM.STA, 901),  # v20d[v3i]
        a.m(ASM.LIN, 900),
        a.m(ASM.SUB, 1130),
        a.m(ASM.OUT, 0),  # numerator of bern
        a.m(ASM.SIN, 900),
        a.m(ASM.LDA, 1131),
        a.m(ASM.SIN, 901),
        a.m(ASM.OUT, 0),  # denominator of bern
        # op25 v3i = v1i + v3i
        a.m(ASM.LDA, 1010),
        a.m(ASM.ADD, 1030),
        a.m(ASM.STA, 1030),
        a.m(ASM.HLT, 0)  # [267] or JMP, 0    (or JMP, 4 don't need 0-3)
    ]

    address = 0
    for instruction in bernoulli:
        computer.ram.memory[address] = instruction
        address += 1

    # data initializations:
    computer.ram.memory[1030] = 2
    # will increment with each run of the program
    # this is which bernoulli number is being calculated
    computer.ram.memory[1210] = 1  # the numerator of the first bern number
    computer.ram.memory[1211] = 6  # the denominator of the first bern number

    # all of the v20n need to be initialized to 0
    # (1220, 1230, 1240, ...) as far as we want to go
    for i in range(1220, 2000, 10):
        computer.ram.memory[i] = 0