def _parse_macro(self, macro_name, args, source_line, line_number, opcode_pos): if macro_name == 'DAT': opcode = [] for arg in args: if arg.type == TokenType.STRING_LITERAL: opcode += list(arg.value.encode('utf-8')) elif arg.type == TokenType.BYTE_LITERAL: opcode.append(arg.value) elif arg.type == TokenType.WORD_LITERAL: opcode += utils.word_to_binary(arg.value) else: _raise_error(source_line, line_number, arg.pos, 'Parameter of macro DAT must be a byte, word or string literal, not {}'.format(arg.type), MacroError) return opcode if macro_name == 'DATN': if len(args) != 2: _raise_error(source_line, line_number, None, 'Macro DATN requires exactly 2 parameters, not {}'.format(len(args)), MacroError) repeat_arg, value_arg = args if repeat_arg.type not in {TokenType.BYTE_LITERAL, TokenType.WORD_LITERAL}: _raise_error(source_line, line_number, repeat_arg.pos, 'The first parameter of macro DATN must be a byte or word literal, not {}'.format(repeat_arg.type), MacroError) repeat_number = repeat_arg.value if value_arg.type not in {TokenType.BYTE_LITERAL, TokenType.WORD_LITERAL, TokenType.STRING_LITERAL}: _raise_error(source_line, line_number, value_arg.pos, 'The second parameter of macro DATN must be a byte, word or string literal, not {}'.format(value_arg.type), MacroError) opcode = [] for _ in range(repeat_number): if value_arg.type == TokenType.STRING_LITERAL: opcode += list(value_arg.value.encode('utf-8')) elif value_arg.type == TokenType.BYTE_LITERAL: opcode.append(value_arg.value) else: opcode += utils.word_to_binary(value_arg.value) return opcode # TODO: add more macros _raise_error(source_line, line_number, None, 'Unknown macro: {}'.format(macro_name), MacroError)
def get_operand_opcode(token): ''' Return operand opcode for a token. Assembler uses it to generate opcode. ''' if token.type == TokenType.WORD_LITERAL: return [ _get_opbyte(OpLen.WORD, OpType.VALUE) ] + utils.word_to_binary(token.value) if token.type == TokenType.BYTE_LITERAL: return [ _get_opbyte(OpLen.BYTE, OpType.VALUE) ] + utils.byte_to_binary(token.value) if token.type == TokenType.ADDRESS_WORD_LITERAL: return [ _get_opbyte(OpLen.WORD, OpType.ADDRESS) ] + utils.word_to_binary(token.value, signed=True) # ^-1234 if token.type == TokenType.WORD_REGISTER: return [ _get_opbyte(OpLen.WORD, OpType.REGISTER, token.value) ] if token.type == TokenType.BYTE_REGISTER: return [ _get_opbyte(OpLen.BYTE, OpType.REGISTER, token.value) ] if token.type in {TokenType.ABS_REF_REG, TokenType.REL_REF_WORD, TokenType.REL_REF_WORD_BYTE, TokenType.REL_REF_WORD_REG}: ref = token.value oplen = { 'B': OpLen.BYTE, 'W': OpLen.WORD, }[ref.length] optype = { TokenType.ABS_REF_REG: OpType.ABS_REF_REG, TokenType.REL_REF_WORD: OpType.REL_REF_WORD, TokenType.REL_REF_WORD_BYTE: OpType.REL_REF_WORD_BYTE, TokenType.REL_REF_WORD_REG: OpType.REL_REF_WORD_REG, }[token.type] if token.type == TokenType.ABS_REF_REG: opreg = ref.base oprest = utils.byte_to_binary(ref.offset, signed=True) # [AX-12] elif token.type == TokenType.REL_REF_WORD: opreg = None oprest = utils.word_to_binary(ref.base, signed=True) # [-1234] elif token.type == TokenType.REL_REF_WORD_BYTE: opreg = None oprest = utils.word_to_binary(ref.base, signed=True) + utils.byte_to_binary(ref.offset) # [-1234+56] elif token.type == TokenType.REL_REF_WORD_REG: opreg = ref.offset oprest = utils.word_to_binary(ref.base, signed=True) # [-1234+AX] return [ _get_opbyte(oplen, optype, opreg) ] + oprest raise InvalidTokenError(token)
def _get_header(self): return ( ALDEBARAN_EXECUTABLE_SIGNATURE + [self.version] + utils.word_to_binary(self.entry_point) + self.extra_header )
def do(self, params): repeat_param, value_param = params if value_param.type == TokenType.STRING_LITERAL: opcode_to_repeat = list(value_param.value.encode('utf-8')) elif value_param.type == TokenType.BYTE_LITERAL: opcode_to_repeat = [value_param.value] else: opcode_to_repeat = utils.word_to_binary(value_param.value) return repeat_param.value * opcode_to_repeat
def set_signed_operand(self, opnum, value): ''' Set value of operand as signed number ''' operand = self.operands[opnum] if operand.oplen == OpLen.BYTE: binary_value = utils.byte_to_binary(value, signed=True) else: binary_value = utils.word_to_binary(value, signed=True) set_operand_value(operand, utils.binary_to_number(binary_value), self.cpu, self.cpu.memory, self.ip)
def do(self, params): opcode = [] for param in params: if param.type == TokenType.STRING_LITERAL: opcode += list(param.value.encode('utf-8')) elif param.type == TokenType.BYTE_LITERAL: opcode.append(param.value) else: opcode += utils.word_to_binary(param.value) return opcode
def get_signed_operand(self, opnum): ''' Return value of operand as signed number ''' operand = self.operands[opnum] raw_value = get_operand_value(operand, self.cpu, self.cpu.memory, self.ip) if operand.oplen == OpLen.BYTE: binary_value = utils.byte_to_binary(raw_value) else: binary_value = utils.word_to_binary(raw_value) return utils.binary_to_number(binary_value, signed=True)
def _get_header(self): return (ALDEBARAN_EXECUTABLE_SIGNATURE + [self.version] + utils.word_to_binary(self.entry_point) + self.extra_header)