Beispiel #1
0
    def test_hdd_write_sector_0(self, cpu):
        value_1 = dec_to_bin(234)
        value_2 = dec_to_bin(52)
        hdd_address_1 = ZEROS
        hdd_address_2 = INT_ONE
        instructions = [move_opcode + a_address + constant_address, hdd_address_1,
                        hdd_opcode + hdd_write + a_address + constant_address, value_1,
                        move_opcode + a_address + constant_address, hdd_address_2,
                        hdd_opcode + hdd_write + a_address + constant_address, value_2
                        ]
        self.load_instructions(cpu.ram, instructions)

        cpu()
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.hdd.data[:16] == value_1

        cpu()
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.hdd.data[:16] == value_1
        assert cpu.hdd.data[16:32] == value_2
Beispiel #2
0
    def test_push_constant_then_pop_to_memory(self, cpu, stack_frame_dec):
        stack_frame = dec_to_bin(stack_frame_dec)
        value_1 = INT_ONE
        memory_address = dec_to_bin(10)

        instructions = [move_opcode + sp_address + constant_address, stack_frame,
                        move_opcode + a_address + constant_address, memory_address,
                        push_opcode + spp_address + constant_address, value_1,
                        pop_opcode + ap_address + spp_address]
        self.load_instructions(cpu.ram, instructions)

        cpu()
        cpu.tick()

        cpu()
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.sp.value == stack_frame
        assert cpu.ram_bus(UNUSED, memory_address, 0) == value_1
Beispiel #3
0
    def test_hdd_write_sector_1(self, cpu):
        value_1 = dec_to_bin(453)
        value_2 = dec_to_bin(531)
        hdd_address_1 = ZEROS
        hdd_address_2 = INT_ONE
        instructions = [hdd_opcode + hdd_set_sector + unused_opcode + constant_address, INT_ONE,
                        move_opcode + a_address + constant_address, hdd_address_1,
                        hdd_opcode + hdd_write + a_address + constant_address, value_1,
                        move_opcode + a_address + constant_address, hdd_address_2,
                        hdd_opcode + hdd_write + a_address + constant_address, value_2
                        ]
        self.load_instructions(cpu.ram, instructions)

        assert cpu() == 0
        cpu.tick()

        cpu()
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.hdd.data[512:512+16] == value_1

        cpu()
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.hdd.data[512:512+16] == value_1
        assert cpu.hdd.data[512+16:512+32] == value_2
Beispiel #4
0
    def test_push_constant_twice(self, cpu, stack_frame_dec):
        stack_frame = dec_to_bin(stack_frame_dec)
        stack_frame_p1 = dec_to_bin(stack_frame_dec - 1)
        stack_frame_p2 = dec_to_bin(stack_frame_dec - 2)
        value_1 = INT_ONE
        value_2 = INT_TWO

        instructions = [move_opcode + sp_address + constant_address, stack_frame,
                        push_opcode + spp_address + constant_address, value_1,
                        push_opcode + spp_address + constant_address, value_2]
        self.load_instructions(cpu.ram, instructions)

        assert cpu() == 0
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.sp.value == stack_frame_p1
        assert cpu.ram_bus(UNUSED, stack_frame, 0) == value_1

        assert cpu() == 0
        cpu.tick()

        assert cpu.sp.value == stack_frame_p2
        assert cpu.ram_bus(UNUSED, stack_frame, 0) == value_1
        assert cpu.ram_bus(UNUSED, stack_frame_p1, 0) == value_2
Beispiel #5
0
    def test_push_twice_then_pop_twice(self, cpu, stack_frame_dec):
        stack_frame = dec_to_bin(stack_frame_dec)
        stack_frame_p1 = dec_to_bin(stack_frame_dec - 1)
        value_1 = INT_ONE
        value_2 = INT_TWO

        instructions = [move_opcode + sp_address + constant_address, stack_frame,
                        push_opcode + spp_address + constant_address, value_1,
                        push_opcode + spp_address + constant_address, value_2,
                        pop_opcode + a_address + spp_address,
                        pop_opcode + b_address + spp_address]
        self.load_instructions(cpu.ram, instructions)

        assert cpu() == 0
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.sp.value == stack_frame_p1
        assert cpu.a.value == value_2

        assert cpu() == 0
        cpu.tick()

        assert cpu.sp.value == stack_frame
        assert cpu.b.value == value_1
Beispiel #6
0
    def test_empty_program(self):
        instructions = []
        labels = {}
        variables = {}

        linked = link(instructions, labels, variables)
        assert linked == [dec_to_bin(2), dec_to_bin(0)]
Beispiel #7
0
    def parse_address(self):
        if not self.tokens:
            raise ParserError('Expected an address. Got end of file.')
        token = self.get_next_token()
        value = None
        is_pointer = False
        if token.type == Delimiter.LeftBracket:
            is_pointer = True
            token = self.get_next_token()

        if token.type in [Label.Name, Literal.Int]:
            address = constantp_address if is_pointer else constant_address
            if token.type == Label.Name:
                if token.value in self.built_ins:
                    value = dec_to_bin(self.built_ins[token.value])
                else:
                    value = token
            if token.type == Literal.Int:
                if type(token.value) != int:
                    raise ParserError(
                        f"Expected literal int value.\nGot '{token.value}'")
                value = dec_to_bin(token.value)
        elif token.type in registers:
            _registers = pointer_registers if is_pointer else registers
            address = _registers[token.type]
        else:
            raise ParserError(
                f"Got unexpected token on line {token.line} while parsing address.\n"
                f"Expected: 'constant', 'register' or '['.\n"
                f"Got: '{token.value}'.")
        if is_pointer:
            self.eat_token(Delimiter.RightBracket)
        return address, value
Beispiel #8
0
    def test_no_labels_as_boot(self):
        instructions = [move_opcode+a_address+constant_address,
                        dec_to_bin(1)]
        labels = {}
        variables = {}

        linked = link(instructions, labels, variables, mode='boot')
        assert linked == [move_opcode+a_address+constant_address,
                          dec_to_bin(1)]
Beispiel #9
0
    def test_no_labels(self):
        instructions = [move_opcode+a_address+constant_address,
                        dec_to_bin(1)]
        labels = {}
        variables = {}

        linked = link(instructions, labels, variables)
        assert linked == [dec_to_bin(4),
                          dec_to_bin(0),
                          move_opcode+a_address+constant_address,
                          dec_to_bin(1)]
Beispiel #10
0
    def test_one_label_as_boot(self):
        instructions = [move_opcode + a_address + constant_address,
                        dec_to_bin(1),
                        jump_opcode + unused_opcode + constant_address,
                        Token(Label.Name, 'start', 4)]
        labels = {'start': 0}
        variables = {}

        linked = link(instructions, labels, variables, mode='boot')
        assert linked == [move_opcode + a_address + constant_address,
                          dec_to_bin(1),
                          jump_opcode + unused_opcode + constant_address,
                          dec_to_bin(0)]
Beispiel #11
0
    def test_double_alloc_size_2_as_boot(self):
        instructions = [move_opcode+constantp_address+a_address,
                        Token(Label.Name, 'var_1', 1),
                        move_opcode + constantp_address + b_address,
                        Token(Label.Name, 'var_2', 2)
                        ]
        labels = {}
        variables = {'var_1': 2, 'var_2': 2}

        linked = link(instructions, labels, variables, mode='boot')
        assert linked == [move_opcode+constantp_address+a_address,
                          dec_to_bin(4),
                          move_opcode + constantp_address + b_address,
                          dec_to_bin(6)]
Beispiel #12
0
    def test_multiple_calls(self):
        instructions = [jump_opcode + unused_opcode + constant_address,
                        Token(Label.Name, 'end', 1),
                        move_opcode + a_address + constant_address,
                        dec_to_bin(1),
                        jump_opcode + unused_opcode + constant_address,
                        Token(Label.Name, 'end', 2),
                        ]
        labels = {'end': 4}
        variables = {}

        linked = link(instructions, labels, variables)
        assert linked == [dec_to_bin(17),  # Program length
                          dec_to_bin(0),  # ALlocated space
                          # Loader
                          pop_opcode+a_address+spp_address,

                          move_opcode + b_address + constant_address,  # move b literal
                          dec_to_bin(10),  # location of first jump to end
                          alu_opcode + alu_add + b_address + a_address,  # add b a
                          alu_opcode + alu_add + bp_address + a_address,  # add [b] a

                          move_opcode + b_address + constant_address,  # move b literal
                          dec_to_bin(14),  # location of second jump to end
                          alu_opcode + alu_add + b_address + a_address,  # add b a
                          alu_opcode + alu_add + bp_address + a_address,  # add [b] a

                          # Program
                          jump_opcode + unused_opcode + constant_address,
                          dec_to_bin(13),  # jump to end
                          move_opcode + a_address + constant_address,
                          dec_to_bin(1),  # literal
                          jump_opcode + unused_opcode + constant_address,
                          dec_to_bin(13)  # jump to end
                          ]
Beispiel #13
0
    def test_alloc_size_1_with_label_as_boot(self):
        instructions = [move_opcode+constantp_address+a_address,
                        Token(Label.Name, 'var', 1),
                        jump_opcode + unused_opcode + constant_address,
                        Token(Label.Name, 'start', 2)
                        ]
        labels = {'start': 0}
        variables = {'var': 1}

        linked = link(instructions, labels, variables, mode='boot')
        assert linked == [move_opcode+constantp_address+a_address,
                          dec_to_bin(4),  # accessing var
                          jump_opcode + unused_opcode + constant_address,
                          dec_to_bin(0)  # jump to label start
                          ]
Beispiel #14
0
    def test_jump_loop(self, cpu):
        instructions = [move_opcode + a_address + constant_address, ZEROS,
                        alu_opcode + alu_inc + a_address + unused_opcode,
                        jump_opcode + unused_opcode + constant_address, dec_to_bin(2)]
        self.load_instructions(cpu.ram, instructions)

        cpu()
        cpu.tick()

        for i in range(10):
            for _ in range(2):
                cpu()
                cpu.tick()

        assert cpu.a.value == dec_to_bin(10)
Beispiel #15
0
 def load_binary(self, binary):
     size = int(len(binary) / 16)
     for i in range(size):
         instruction = binary[i * 16:(i + 1) * 16]
         address = dec_to_bin(i)
         self.cpu.ram(instruction, address, 1)
     self.cpu.ram.tick()
Beispiel #16
0
    def test_move_from_register_to_constant_as_pointer(self, cpu):
        memory_address = dec_to_bin(1024)
        value = INT_ONE
        instructions = [move_opcode + a_address + constant_address, value,
                        move_opcode + constantp_address + a_address, memory_address,
                        ]
        self.load_instructions(cpu.ram, instructions)

        assert cpu() == 0
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.ram_bus(UNUSED, memory_address, 0) == value
        assert cpu.pc(UNUSED, 0, 0, 0) == dec_to_bin(4)
Beispiel #17
0
    def test_call_constant(self, cpu):
        stack_frame = dec_to_bin(1024)
        function_address = dec_to_bin(52)
        instructions = [move_opcode + sp_address + constant_address, stack_frame,
                        call_opcode + spp_address + constant_address, function_address]
        self.load_instructions(cpu.ram, instructions)

        cpu()
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.pc.register.value == function_address
        assert cpu.ram_bus(UNUSED, stack_frame, 0) == dec_to_bin(4)
        assert cpu.sp.value == dec_to_bin(1023)
Beispiel #18
0
 def test_push_or_call_literal(self, parser, keyword_token, opcode,
                               literal):
     tokens = [keyword_token, Token(Literal.Int, literal, 1)]
     instructions = parser.parse(tokens)
     assert instructions == [
         opcode + spp_address + constant_address,
         dec_to_bin(literal)
     ]
Beispiel #19
0
 def test_BP_label(self, parser):
     token_bp_label = Token(Label.Name, 'BP', 1)
     tokens = [token_move, token_sp, token_bp_label]
     instructions = parser.parse(tokens)
     base_pointer_address = dec_to_bin(32767)
     assert instructions == [
         move_opcode + sp_address + constant_address, base_pointer_address
     ]
Beispiel #20
0
 def test_source_address_command_literal(self, parser, command_token,
                                         opcode, literal):
     tokens = [command_token, Token(Literal.Int, literal, 1)]
     instructions = parser.parse(tokens)
     assert instructions == [
         opcode + unused_opcode + constant_address,
         dec_to_bin(literal)
     ]
Beispiel #21
0
 def test_two_address_command_literal_to_register(self, parser,
                                                  command_token, opcode,
                                                  token, address, value):
     tokens = [command_token, token, Token(Literal.Int, value, 1)]
     instructions = parser.parse(tokens)
     assert instructions == [
         opcode + address + constant_address,
         dec_to_bin(value)
     ]
Beispiel #22
0
    def test_alloc_size_1_as_boot(self):
        instructions = [move_opcode+constantp_address+a_address,
                        Token(Label.Name, 'var', 1)
                        ]
        labels = {}
        variables = {'var': 1}

        linked = link(instructions, labels, variables, mode='boot')
        assert linked == [move_opcode+constantp_address+a_address,
                          dec_to_bin(2)]
Beispiel #23
0
def make_loader(relative_locations):
    loader = [pop_opcode + a_address + spp_address]  # pop a
    offset = len(loader) + 4 * len(relative_locations)
    for access_location in relative_locations:
        loader.append(move_opcode + b_address +
                      constant_address)  # move b literal
        loader.append(dec_to_bin(access_location + offset))
        loader.append(alu_opcode + alu_add + b_address + a_address)  # add b a
        loader.append(alu_opcode + alu_add + bp_address +
                      a_address)  # add [b] a
    return loader
Beispiel #24
0
 def test_two_address_command_literal_pointer_to_register(
         self, parser, command_token, opcode, token, address, value):
     tokens = [
         command_token, token, token_left_bracket,
         Token(Literal.Int, value, 1), token_right_bracket
     ]
     instructions = parser.parse(tokens)
     assert instructions == [
         opcode + address + constantp_address,
         dec_to_bin(value)
     ]
Beispiel #25
0
 def test_SCREEN_label(self, parser):
     token_screen_label = Token(Label.Name, 'SCREEN', 1)
     tokens = [
         token_move, token_a, token_left_bracket, token_screen_label,
         token_right_bracket
     ]
     instructions = parser.parse(tokens)
     screen_address = dec_to_bin(32768)
     assert instructions == [
         move_opcode + a_address + constantp_address, screen_address
     ]
Beispiel #26
0
 def test_KEYBOARD_label(self, parser):
     token_keyboard_label = Token(Label.Name, 'KEYBOARD', 1)
     tokens = [
         token_move, token_a, token_left_bracket, token_keyboard_label,
         token_right_bracket
     ]
     instructions = parser.parse(tokens)
     keyboard_address = dec_to_bin(40960)
     assert instructions == [
         move_opcode + a_address + constantp_address, keyboard_address
     ]
Beispiel #27
0
    def test_alloc_size_1(self):
        instructions = [move_opcode+constantp_address+a_address,
                        Token(Label.Name, 'var', 1)]
        labels = {}
        variables = {'var': 1}

        linked = link(instructions, labels, variables)
        assert linked == [dec_to_bin(9),  # Length of program
                          dec_to_bin(1),  # Allocated memory

                          # Loader
                          pop_opcode + a_address + spp_address,
                          move_opcode + b_address + constant_address,  # move b literal
                          dec_to_bin(6),  # location of var access
                          alu_opcode + alu_add + b_address + a_address,  # add b a
                          alu_opcode + alu_add + bp_address + a_address,  # add [b] a

                          # Program
                          move_opcode+constantp_address+a_address,
                          dec_to_bin(7),  # Accessing var
                          ]
Beispiel #28
0
    def test_push_from_register(self, cpu, stack_frame_dec):
        stack_frame = dec_to_bin(stack_frame_dec)
        stack_frame_p1 = dec_to_bin(stack_frame_dec - 1)
        value_1 = INT_ONE

        instructions = [move_opcode + sp_address + constant_address, stack_frame,
                        move_opcode + a_address + constant_address, value_1,
                        push_opcode + spp_address + a_address]
        self.load_instructions(cpu.ram, instructions)

        cpu()
        cpu.tick()

        cpu()
        cpu.tick()

        assert cpu() == 0
        cpu.tick()

        assert cpu.sp.value == stack_frame_p1
        assert cpu.ram_bus(UNUSED, stack_frame, 0) == value_1
Beispiel #29
0
    def test_double_alloc_size_2(self):
        instructions = [move_opcode+constantp_address+a_address,
                        Token(Label.Name, 'var_1', 1),
                        move_opcode + constantp_address + b_address,
                        Token(Label.Name, 'var_2', 2)
                        ]
        labels = {}
        variables = {'var_1': 2, 'var_2': 2}

        linked = link(instructions, labels, variables)
        assert linked == [dec_to_bin(15),  # Length of program
                          dec_to_bin(4),  # Allocated memory

                          # Loader
                          pop_opcode + a_address + spp_address,

                          move_opcode + b_address + constant_address,  # move b literal
                          dec_to_bin(10),  # location of var_1 access
                          alu_opcode + alu_add + b_address + a_address,  # add b a
                          alu_opcode + alu_add + bp_address + a_address,  # add [b] a

                          move_opcode + b_address + constant_address,  # move b literal
                          dec_to_bin(12),  # location of var_2 access
                          alu_opcode + alu_add + b_address + a_address,  # add b a
                          alu_opcode + alu_add + bp_address + a_address,  # add [b] a

                          # Program
                          move_opcode+constantp_address+a_address,
                          dec_to_bin(13),  # Accessing var_1
                          move_opcode + constantp_address + b_address,
                          dec_to_bin(15),  # Accessing var_2
                          ]
Beispiel #30
0
    def test_alloc_size_1_with_label(self):
        instructions = [move_opcode+constantp_address+a_address,
                        Token(Label.Name, 'var', 1),
                        jump_opcode + unused_opcode + constant_address,
                        Token(Label.Name, 'start', 2)
                        ]
        labels = {'start': 0}
        variables = {'var': 1}

        linked = link(instructions, labels, variables)
        assert linked == [dec_to_bin(15),  # Length of program
                          dec_to_bin(1),  # Allocated memory

                          # Loader
                          pop_opcode + a_address + spp_address,

                          move_opcode + b_address + constant_address,  # move b literal
                          dec_to_bin(10),  # location of var access
                          alu_opcode + alu_add + b_address + a_address,  # add b a
                          alu_opcode + alu_add + bp_address + a_address,  # add [b] a

                          move_opcode + b_address + constant_address,  # move b literal
                          dec_to_bin(12),  # location of jump to start
                          alu_opcode + alu_add + b_address + a_address,  # add b a
                          alu_opcode + alu_add + bp_address + a_address,  # add [b] a

                          # Program
                          move_opcode+constantp_address+a_address,
                          dec_to_bin(13),  # accessing var
                          jump_opcode + unused_opcode + constant_address,
                          dec_to_bin(9)  # jump to label start
                          ]