File size: 2,746 Bytes
324ecd2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import unittest
from beamboot.two_layer_cpu import TwoLayerCPU
from beamboot.large_cpu import LargeCPU, LargeRuntime


class TwoLayerCPUTests(unittest.TestCase):
    def test_compiled_address_and_transition(self):
        program = [('LDI', 7), ('STORE', 3), ('LDI', 2), ('ADDM', 3),
                   ('STORE', 4), ('LOAD', 3), ('OUT', 0), ('LOAD', 4),
                   ('OUT', 0), ('SUB', 9), ('JZ', 12), ('HALT', 0), ('HALT', 0)]
        actual, ref = TwoLayerCPU(program), LargeRuntime(LargeCPU(program))
        for _ in range(30):
            result, expected = actual.step(), ref.step()
            self.assertEqual(result, expected)
            if result.halt: break
        self.assertTrue(actual.halted)

    def test_rom_is_not_read_by_host_after_compilation(self):
        program = [('LDI', 11), ('STORE', 8), ('LDI', 0), ('LOAD', 8), ('OUT', 0), ('HALT', 0)]
        machine = TwoLayerCPU(program)
        machine.program = None
        output = []
        for _ in range(10):
            step = machine.step()
            if step.output: output.append(step.acc)
            if step.halt: break
        self.assertEqual(output, [11])
        self.assertTrue(machine.halted)

    def test_boot_and_commands(self):
        from beamboot.os import OperatingMonitor
        machine = OperatingMonitor(backend='two-layer')
        self.assertEqual(machine.boot(), 'BEAM>\n')
        self.assertEqual(machine.version(), 'BEAMBOOT 0.1\n')
        self.assertEqual(machine.add(7, 8), 15)
        self.assertEqual(machine.add(15, 3), 2)

    def test_seeded_programs_against_python_interpreter(self):
        import random
        rng = random.Random(519)
        ops = ('LDI', 'ADD', 'SUB', 'LOAD', 'STORE', 'ADDM', 'SUBM', 'OUT')
        for _ in range(3):
            program = [(rng.choice(ops), rng.randrange(16)) for _ in range(50)] + [('HALT', 0)]
            machine = TwoLayerCPU(program)
            machine.program = None
            ram, acc = [0] * 16, 0
            for pc, (op, arg) in enumerate(program):
                step = machine.step()
                if op == 'LDI': acc = arg
                elif op == 'ADD': acc = (acc + arg) & 15
                elif op == 'SUB': acc = (acc - arg) & 15
                elif op == 'LOAD': acc = ram[arg]
                elif op == 'STORE': ram[arg] = acc
                elif op == 'ADDM': acc = (acc + ram[arg]) & 15
                elif op == 'SUBM': acc = (acc - ram[arg]) & 15
                self.assertEqual((step.pc, step.acc), (pc if op == 'HALT' else pc + 1, acc))
                self.assertEqual((step.write, step.output, step.halt), (op == 'STORE', op == 'OUT', op == 'HALT'))
                if step.write: self.assertEqual((step.address, step.value), (arg, acc))