def __execute_debug_command(command: list, machine: EmulatorBase,
                            profile: Profile):
    if config.disable_debug:
        return

    if len(command) == 1:
        command_str: str = command[0]
        if command_str.lower() == 'break':
            debug.breakpoint()
        elif command_str.lower() == 'ram':
            ram = machine.exec_command(None, 'get_ram_ref', [])
            debug.ram_display(ram, profile.adressing.bin_len, 0, None)
        elif command_str.lower() == 'regs':
            regs = machine.exec_command(None, 'get_regs_ref', [])
            print(regs)
    elif command[0] == 'log':
        pos = machine.get_current_pos(None)
        debug.log(f"{pos}  {' '.join(command[1:])}")
    elif '(' in command and ')' in command:
        cmd: str = command[0]
        start = command.index('(')
        end = command.index(')')
        if start != 1:
            raise error.EmulationError(f"Bad debug cmd: {command}")
        args = [token for token in command[(start + 1):end] if token != ',']

        if cmd.startswith("ram") and len(args) == 2:
            min_adress, max_adress = int(args[0]), int(args[1])
            ram = machine.exec_command(None, 'get_ram_ref', [])
            debug.ram_display(ram, profile.adressing.bin_len, min_adress,
                              max_adress)
        else:
            machine.exec_command(None, cmd, args)
def pack_adresses(instructions):
    output = dict()
    for adress, data in instructions.items():
        for i, cell in enumerate(data):
            if (adress + i) in output:
                raise error.EmulationError(
                    f"Output data is overlapping: adress: {adress+i} is arleady occuped by value: {output[adress+i]}"
                )
            output[adress + i] = cell
    return output
def emulate(output, context):
    print("Custom emulation pipeline")
    profile: core.profile.profile.Profile = context['profile']
    emul: dict = profile.emul

    save_settings = emul["output"]["save"]
    data_settings = emul["output"]["data"]
    emulation_settings = emul["emulation"]
    
    config.override_from_dict(save_settings)
    
    save_pipeline = core.pipeline.make_save_pipeline()
    
    output, context = core.pipeline.exec_pipeline(save_pipeline, output, context, progress_bar_name='Saving Binary')

    process = [emulation_settings["path"], *emulation_settings["args"]]

    print(f"Calling: {' '.join(process)}")
    print("Emulation Output:\n")

    try:
        subprocess.check_call(process)
    except subprocess.CalledProcessError as err:
        raise error.EmulationError(f"Emulation Error: {err}")
Exemple #4
0
    def parse_command(self):
        low = Binary(int(self.RAM[self.ROM_COUNTER]), bit_lenght=8)
        cu = int(low[4:])
        r1 = int(low[:2])
        r2 = int(low[2:4])

        if cu == 0:
            r1r2 = int(low[:4])
            if r1r2 == 0:
                print("Shuting with error")
                self.is_running_flag = False
            elif r1r2 == 1:
                self.is_running_flag = False
            elif r1r2 == 2:
                self.inc_counter()
                n1 = int(self.RAM[self.ROM_COUNTER])
                self.jump(n1)
                return
            elif r1r2 == 3:
                self.inc_counter()
                n1 = int(self.RAM[self.ROM_COUNTER])
                self.jump_flag(n1)
                return
            elif r1r2 == 4:
                self.interutp(None, None)
            elif r1r2 == 5:
                self.clear_screen()
            else:
                raise error.EmulationError("Command is not implemented")

        elif cu == 1:
            if r2 == 0:
                self.inc_counter()
                n1 = int(self.RAM[self.ROM_COUNTER])
                self.mov_const_reg(n1, r1)
            elif r2 == 1:
                self.alu_reg_inc(r1)
            elif r2 == 2:
                self.alu_reg_dec(r1)
            elif r2 == 3:
                raise
        elif cu == 2:
            self.mov_reg_reg(r2, r1)
        elif cu == 3:
            self.alu_reg_reg_add(r2, r1)
        elif cu == 4:
            self.alu_reg_reg_sub(r2, r1)
        elif cu == 5:
            self.alu_reg_reg_rsh(r2, r1)
        elif cu == 6:
            self.alu_reg_reg_lsh(r2, r1)
        elif cu == 7:
            self.alu_reg_reg_and(r2, r1)
        elif cu == 8:
            self.alu_reg_reg_or(r2, r1)
        elif cu == 9:
            self.alu_reg_reg_xor(r2, r1)
        elif cu == 10:  #JUMP EQUAL
            zf, _ = self.alu_reg_reg_cmp(r2, r1)
            if zf == True:
                self.inc_counter()
                n1 = self.RAM[self.ROM_COUNTER]
                self.jump(n1)
                return
            else:
                self.inc_counter()
        elif cu == 11:  #JUMP GREATER
            zf, of = self.alu_reg_reg_cmp(r2, r1)
            if zf == False and of == True:
                self.inc_counter()
                n1 = self.RAM[self.ROM_COUNTER]
                self.jump(n1)
                return
            else:
                self.inc_counter()
        elif cu == 12:
            self.read_reg_pointer(r2, r1)
        elif cu == 13:
            self.inc_counter()
            n1 = self.RAM[self.ROM_COUNTER]
            self.read_ram_reg(n1, r1)
        elif cu == 14:
            self.write_pointer_reg(r1, r2)
        elif cu == 15:
            self.inc_counter()
            n1 = self.RAM[self.ROM_COUNTER]
            self.write_const_reg(r1, n1)
        else:
            raise error.EmulationError("Unreachable")

        self.inc_counter()
Exemple #5
0
 def ret(self):
     if len(self.ROMStack) == 0:
         raise error.EmulationError("ROM")
     addres = self.ROMStack.pop()
     self.jump(addres)
Exemple #6
0
 def call(self, _target_true):
     if len(self.ROMStack) < 15:
         self.ROMStack.append(self.ROM_COUNTER)
     else:
         raise error.EmulationError("rom stack overflow")
     self.jump(_target_true)
def emulate(program, context):
    global GLOBAL_CURR_ADRESS

    profile: Profile = context["profile"]
    emulator = profile.emul

    try:
        machine: EmulatorBase = emulator.get_emulator()
    except:
        raise error.EmulationError(
            "File with emulator definition should define the 'get_emulator' function"
        )

    if machine is None or not isinstance(machine, EmulatorBase):
        raise error.EmulationError(
            f"Function get_emulator returned unvalid instance of machine expected: 'EmulatorBase', got '{machine}'"
        )

    print()
    print("Writing data to device")

    __write_program(program, context, machine)
    __write_data(program, context, machine)

    debug_instructions = context["debug_instructions"]

    print("Starting Emulation")

    emulate_start_time = time.thread_time_ns()
    emulation_cycles = 1
    machine_cycles = 0

    while machine.is_running():
        pos = machine.get_current_pos(None)
        GLOBAL_CURR_ADRESS = pos

        if pos in debug_instructions:
            for instruction in (i for i in debug_instructions[pos]
                                if 'pre' in i):
                __execute_debug_command(instruction['pre'], machine, profile)

        machine.next_tick()

        if pos in debug_instructions:
            for instruction in (i for i in debug_instructions[pos]
                                if 'post' in i):
                __execute_debug_command(instruction['post'], machine, profile)

        emulation_cycles += 1
        machine_cycles += machine.get_machine_cycles()
    emulate_end_time = time.thread_time_ns()

    print("Emulation finished")
    print(f"Took: {(emulate_end_time-emulate_start_time)/1000000.0}ms")
    try:
        print(
            f"Per command: {(emulate_end_time-emulate_start_time)/emulation_cycles/1000.0:0.2f}μs"
        )
    except:
        print(
            f"Per command: {(emulate_end_time-emulate_start_time)/emulation_cycles/1000.0:0.2f}us"
        )
    print(
        f"Machine took: {machine_cycles} steps, estimated execution time: {machine_cycles/float(profile.info.speed):0.1f}s"
    )
Exemple #8
0
def generate_ram_display(RAM,
                         rows=16,
                         subrows=1,
                         ADRESS_AS_HEX=True,
                         VALUE_AS="bin",
                         ADD_ASCII_VIEW=True,
                         WORD_SIZE=8,
                         start=0,
                         end=None):
    """
    It just works.
    """
    if start != 0:
        start = start + (rows - start % rows) - rows
    else:
        start = 0
    if end is not None:
        end = end + (rows - end % rows)
    else:
        end = len(RAM)

    if rows % subrows != 0:
        raise error.EmulationError(
            "Row number should be dividable by subrow count.")

    def generate_value(PAD=-1, MODE="dec"):
        ADRESS = ""
        try:
            val = RAM[adress + i]
        except IndexError:
            raise
        if MODE == "dec":
            PAD = len(str(int(2**WORD_SIZE) - 1)) + 1
            ADRESS = str(val)
        elif MODE == "hex":
            PAD = len(str(hex(2**WORD_SIZE - 1)[2:])) + 1
            ADRESS = str(formatter.padhex(val, 2, False))
        elif MODE == "bin":
            PAD = len(str(bin(2**WORD_SIZE - 1)[2:])) + 1
            ADRESS = formatter.padbin(val, 8, False)
        return '{}{}'.format(" " * (PAD - len(ADRESS)), ADRESS)

    totalrows = rows
    rows //= subrows
    LINE_START = 0
    subrow_cunter = 0
    OUTPUT = "\n"

    if config.RAM_DEBUG_MODE == "simple":
        return '\n'.format(RAM)
    elif config.RAM_DEBUG_MODE == "row":
        try:
            for adress in range(0, len(RAM), rows):
                if not (adress in range(start, end)):
                    continue

                if subrow_cunter == 0:
                    LINE_START = adress
                rows_data = ""
                for i in range(rows):
                    rows_data += generate_value(-1, VALUE_AS)

                if ADD_ASCII_VIEW:
                    if subrow_cunter == (subrows - 1):
                        asciirep = ""
                        for i in range(totalrows):
                            char_id = RAM[LINE_START + i]
                            asciirep += chr(
                                char_id
                            ) if char_id >= 32 and char_id < 127 else "."

                        rows_data += "\t{}".format(asciirep)

                if ADRESS_AS_HEX:
                    OUTPUT += " {}:{}{}".format(
                        formatter.padhex(adress, len(hex(len(RAM) - 1)[2:])),
                        rows_data, " " if subrow_cunter !=
                        (subrows - 1) else "\n")
                else:
                    OUTPUT += " {}:{}{}".format(
                        adress, rows_data, " " if subrow_cunter !=
                        (subrows - 1) else "\n")
                subrow_cunter = (subrow_cunter + 1) % subrows
        except Exception as err:
            pass

        return OUTPUT