URL
https://opencores.org/ocsvn/2d_game_console/2d_game_console/trunk
Subversion Repositories 2d_game_console
[/] [2d_game_console/] [trunk/] [Assembler/] [assembler.py] - Rev 2
Compare with Previous | Blame | View Log
#Author: Lucas Alves #License: Public Domain #Assembler #import string import sys from tkinter import * from tkinter import filedialog from tkinter import messagebox import os labels_dict = {} register_dict = {'R0':0, 'R1':1, 'R2':2, 'R3':3, 'R4':4, 'R5':5, 'R6':6, 'R7':7, 'R8':8, 'R9':9, 'R10':10, 'R11':11, 'R12':12, 'R13':13, 'R14':14, 'R15':15, 'R16':16, 'R17':17, 'R18':18, 'R19':19, 'R20':20, 'R21':21, 'R22':22, 'R23':23, 'R24':24, 'R25':25, 'R26':26, 'R27':27, 'R28':28, 'R29':29, 'R30':30, 'R31':31} # Interrupt Service Routines labels isr_labels_list = ['.ISR0', '.ISR1', '.ISR2', '.ISR3'] # Number of Interrupt Service Routines isr_num = len(isr_labels_list) # INSTRUCTIONS OPERATION CODE # # Graphical instructions opcode_sprite_id = "110001" opcode_sprite_color = "110010" opcode_sprite_pos = "110100" opcode_sprite_collision_bg = "110101" opcode_sprite_collision_sp = "110110" opcode_wait_vsync = "110111" # Arithmetic Instructions opcode_add = "010001" opcode_sub = "010010" opcode_mul = "010100" opcode_div = "010101" # Logical Instructions opcode_and = "100001" opcode_or = "100010" opcode_cmp = "100100" opcode_not = "100101" # Control Transfer Instructions (Immediate) opcode_jmp = "101001" opcode_brfl = "101010" opcode_call = "101011" opcode_ret = "101100" opcode_iret = "101101" opcode_nop = "101110" # Control Transfer Instructions (Register) opcode_jr = "011001" opcode_brflr = "011010" opcode_callr = "011011" # Data Transfer Instructions opcode_lw = "001001" opcode_sw = "001010" opcode_limm = "001100" class AssemblerGUI: # Contructor def __init__(self): self.root = Tk() self.root.title("asm2mif Assembler") self.root.resizable(False, False) memoryFrame = Frame(self.root) memoryFrame.pack(fill=BOTH) memoryLabel = Label(memoryFrame, text="Total size of memory in words") memoryLabel.pack(side=LEFT, padx=5, pady=5) self.memoryEntry = Entry(memoryFrame, width=10) self.memoryEntry.insert(0, "65536") self.memoryEntry.pack(side=LEFT, padx=5, pady=5) fileLabelFrame = Frame(self.root) fileLabelFrame.pack(fill=BOTH) fileLabel = Label(fileLabelFrame, text="Assembly file:") fileLabel.pack(side=LEFT, padx=5, pady=0) fileFrame = Frame(self.root) fileFrame.pack(fill=BOTH) self.fileEntry = Entry(fileFrame, width=50) self.fileEntry.pack(side=LEFT, padx=5, pady=0) browseButton = Button(fileFrame, text="Browse", fg="black", command=self.ask_open_file) browseButton.pack(side=LEFT, padx=5, pady=0) okFrame = Frame(self.root) okFrame.pack(fill=BOTH, expand=False) okButton = Button(okFrame, text="Save As...", command=self.check_info) okButton.pack(side=RIGHT, padx=5, pady=5) self.root.mainloop() def ask_open_file(self): currdir = os.getcwd() self.filenameOpened = filedialog.askopenfilename(parent=self.root, initialdir=currdir, title='Open file', filetypes = (("Assembly files","*.asm"),("All files","*.*"))) if len(self.filenameOpened) > 0: self.fileEntry.delete(0, END) self.fileEntry.insert(0, self.filenameOpened) def ask_save_file(self): currdir = os.getcwd() self.filenameSaved = filedialog.asksaveasfilename(parent=self.root, initialdir=currdir, title='Save file', defaultextension='.mif', filetypes = [("Memory Initialization File","*.mif")]) if len(self.filenameSaved) > 0: self.execute() def check_info(self): self.memorySize = self.memoryEntry.get() if self.memorySize.isdigit() is True: self.memorySize = int(self.memorySize) self.filenameOpened = self.fileEntry.get() if os.path.isfile(self.filenameOpened) is True: self.ask_save_file() else: messagebox.showerror(title='Error', message='Please enter a valid input file.') else: messagebox.showerror(title='Error', message='Please enter a valid memory size.') def quit(self): self.root.destroy() sys.exit() def execute(self): asm_file = open(self.filenameOpened) original_text = asm_file.readlines() new_text = list(original_text) asm_file.close() # Removes comments for line_index, line in enumerate(new_text): new_text[line_index] = line.strip() find_index = new_text[line_index].find("//") if find_index == -1: continue elif find_index == 0: new_text[line_index] = '' else: new_text[line_index] = new_text[line_index][:(find_index)] new_text[line_index] = new_text[line_index].strip() # Removes empty elements new_text = list(filter(lambda x : x != '', new_text)) # Removes lines with labels and saves address for line_index, line in enumerate(new_text, isr_num): find_index = line.find(":") if find_index == -1: continue elif find_index == 0: messagebox.showerror(title='Error', message='Unamed label at address {}.'.format(line_index)) self.quit() else: label = line[:(find_index)] if label in labels_dict: messagebox.showerror(title='Error', message='Label "{}" repeated at address {}.'.format(label, line_index)) self.quit() else: labels_dict[label] = line_index new_text.pop(line_index - isr_num) #print (labels_dict.items()) #for index2, line2 in enumerate(new_text): # print (index2, line2) self.mif_file = open(self.filenameSaved, 'w') self.mif_file.write('DEPTH = ' + str(self.memorySize) + '; -- The size of memory in words\n') self.mif_file.write('WIDTH = 32; -- The size of data in bits\n') self.mif_file.write('ADDRESS_RADIX = UNS; -- The radix for address values\n') self.mif_file.write('DATA_RADIX = BIN; -- The radix for data values\n') self.mif_file.write('CONTENT -- Start of (address : data pairs)\n') self.mif_file.write('BEGIN\n\n') # Search for Interrupt Service Routines labels on labels_dict dictionary for index, isr_label in enumerate(isr_labels_list): self.mif_file.write(str(index) + ' : ') # Instruction memory address if isr_label in labels_dict: address = labels_dict.get(isr_label, -1) if (address == -1): print('erro, label não existe') sys.exit("erro, label não existe") else: bin_address = '{0:016b}'.format(address) self.mif_file.write(opcode_jmp + '') # JMP Opcode self.mif_file.write('0000000000' + '') # Blank space self.mif_file.write(bin_address + ';') # Label address self.mif_file.write(' -- ' + isr_label + ': JMP ' + str(address) + '\n') # Assembly instruction as a comment else: self.mif_file.write(opcode_iret + '') # RET Opcode self.mif_file.write('00000000000000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + isr_label + ': IRET \n') # Assembly instruction as a comment # Identifies instruction and calls corresponding function for line_index, line in enumerate(new_text, isr_num): #print (line_index, line) words = line.split() if words[0] == "LW": self.lw_instruct(line_index, line) elif words[0] == "SW": self.sw_instruct(line_index, line) elif words[0] == "LIMM": self.limm_instruct(line_index, line) elif words[0] == "ADD": self.add_instruct(line_index, line) elif words[0] == "SUB": self.sub_instruct(line_index, line) elif words[0] == "MUL": self.mul_instruct(line_index, line) elif words[0] == "DIV": self.div_instruct(line_index, line) elif words[0] == "AND": self.and_instruct(line_index, line) elif words[0] == "OR": self.or_instruct(line_index, line) elif words[0] == "CMP": self.cmp_instruct(line_index, line) elif words[0] == "NOT": self.not_instruct(line_index, line) elif words[0] == "JR": self.jr_instruct(line_index, line) elif words[0] == "BRFL": self.brfl_instruct(line_index, line) elif words[0] == "BRFLR": self.brflr_instruct(line_index, line) elif words[0] == "CALL": self.call_instruct(line_index, line) elif words[0] == "CALLR": self.callr_instruct(line_index, line) elif words[0] == "RET": self.ret_instruct(line_index, line) elif words[0] == "IRET": self.iret_instruct(line_index, line) elif words[0] == "NOP": self.nop_instruct(line_index, line) elif words[0] == "JMP": self.jmp_instruct(line_index, line) elif words[0] == "SPRITE_ID": self.sprite_id_instruct(line_index, line) elif words[0] == "SPRITE_COLOR": self.sprite_color_instruct(line_index, line) elif words[0] == "SPRITE_POS": self.sprite_pos_instruct(line_index, line) elif words[0] == "SPRITE_COLLISION_BG": self.sprite_collision_bg_instruct(line_index, line) elif words[0] == "SPRITE_COLLISION_SP": self.sprite_collision_sp_instruct(line_index, line) elif words[0] == "WAIT_VSYNC": self.wait_vsync_instruct(line_index, line) else: messagebox.showerror(title='Error', message='"{}" instruction at address {} does not exist.'.format(words[0], line_index)) self.quit() self.mif_file.write('[' + str(line_index+1) + '..' + str(self.memorySize-1) + '] : 00000000000000000000000000000000;\n') self.mif_file.write('END;') self.mif_file.close() messagebox.showinfo(parent=self.root, title='Info', message='Done!') self.quit() def lw_instruct(self, line_index, line): params = line.split(',') # params[0]: LW Rd # params[1]: Imm(Rb) or (Rb) if (len(params) != 2): print('erro, número de operandos errado') sys.exit("erro, número de operandos errado") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: LW # words[1]: Rd # words[2]: Imm(Rb) or (Rb) #print(words) ################################# if (len(words) != 3): print('erro, número de operandos errado') sys.exit("erro, número de operandos errado") else: words[2] = words[2].strip() #print(words) ################################# # Addressing Mode: Register if words[2][0] == '(': words[2] = words[2].strip('(') words[2] = words[2].strip(')') words[2] = words[2].strip() # words[0]: LW # words[1]: Rd # words[2]: Rb #print(words) ################################# reg_d = words[1] reg_b = words[2] num_reg_d = register_dict.get(reg_d, -1) num_reg_b = register_dict.get(reg_b, -1) if (num_reg_d == -1 or num_reg_b == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_b = '{0:05b}'.format(num_reg_b) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_lw + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_b + '') # Source register self.mif_file.write('0000000000000000;') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment # Addressing Mode: Base-Offset else: params = words[2].split('(') words.remove(words[2]) words.extend(params) #print(words) ################################# # Addressing Mode: Base-Offset if(len(words) == 4): words[2] = words[2].strip() words[3] = words[3].strip(')') words[3] = words[3].strip() # words[0]: LW # words[1]: Rd # words[2]: Imm # words[3]: Rb #print(words) ################################# reg_d = words[1] imm = int(words[2]) reg_b = words[3] num_reg_d = register_dict.get(reg_d, -1) num_reg_b = register_dict.get(reg_b, -1) if (num_reg_d == -1 or num_reg_b == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_b = '{0:05b}'.format(num_reg_b) bin_imm = '{0:016b}'.format(imm & 0b1111111111111111) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_lw + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_b + '') # Source register self.mif_file.write(bin_imm + ';') # Immediate value self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment else: print('erro, número de operandos errado') sys.exit("erro, número de operandos errado") return def sw_instruct(self, line_index, line): params = line.split(',') # params[0]: SW Rd # params[1]: Imm(Rb) or (Rb) if (len(params) != 2): print('erro, número de operandos errado') sys.exit("erro, número de operandos errado") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: SW # words[1]: Rd # words[2]: Imm(Rb) or (Rb) #print(words) ################################# if (len(words) != 3): print('erro, número de operandos errado') sys.exit("erro, número de operandos errado") else: words[2] = words[2].strip() #print(words) ################################# # Addressing Mode: Register if words[2][0] == '(': words[2] = words[2].strip('(') words[2] = words[2].strip(')') words[2] = words[2].strip() # words[0]: SW # words[1]: Rd # words[2]: Rb #print(words) ################################# reg_d = words[1] reg_b = words[2] num_reg_d = register_dict.get(reg_d, -1) num_reg_b = register_dict.get(reg_b, -1) if (num_reg_d == -1 or num_reg_b == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_b = '{0:05b}'.format(num_reg_b) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_sw + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_b + '') # Source register self.mif_file.write('0000000000000000;') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment # Addressing Mode: Base-Offset else: params = words[2].split('(') words.remove(words[2]) words.extend(params) #print(words) ################################# # Addressing Mode: Base-Offset if(len(words) == 4): words[2] = words[2].strip() words[3] = words[3].strip(')') words[3] = words[3].strip() # words[0]: SW # words[1]: Rd # words[2]: Imm # words[3]: Rb #print(words) ################################# reg_d = words[1] imm = int(words[2]) reg_b = words[3] num_reg_d = register_dict.get(reg_d, -1) num_reg_b = register_dict.get(reg_b, -1) if (num_reg_d == -1 or num_reg_b == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_b = '{0:05b}'.format(num_reg_b) bin_imm = '{0:016b}'.format(imm & 0b1111111111111111) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_sw + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_b + '') # Source register self.mif_file.write(bin_imm + ';') # Immediate value self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment else: print('erro, número de operandos errado') sys.exit("erro, número de operandos errado") return def limm_instruct(self, line_index, line): params = line.split(',') # params[0]: LIMM Rd # params[1]: Imm if (len(params) != 2): print('erro, número de operandos errado') sys.exit("erro, número de operandos errado") else: words = params[0].split() params.remove(params[0]) words.extend(params) words[2] = words[2].strip() # words[0]: LIMM # words[1]: Rd # words[2]: Imm if (len(words) != 3): print('erro, número de operandos errado') sys.exit("erro, número de operandos errado") else: reg_d = words[1] imm = int(words[2]) num_reg_d = register_dict.get(reg_d, -1) if (num_reg_d == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_imm = '{0:016b}'.format(imm & 0b1111111111111111) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_limm + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write('00000' + '') # Blank space self.mif_file.write(bin_imm + ';') # Immediate value self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def add_instruct(self, line_index, line): params = line.split(',') if (len(params) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: ADD # words[1]: Rd # words[2]: Rs reg_d = words[1].strip() reg_s = words[2].strip() num_reg_d = register_dict.get(reg_d, -1) num_reg_s = register_dict.get(reg_s, -1) if (num_reg_d == -1 or num_reg_s == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_s = '{0:05b}'.format(num_reg_s) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_add + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_s + '') # Source register self.mif_file.write('0000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def sub_instruct(self, line_index, line): params = line.split(',') if (len(params) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: SUB # words[1]: Rd # words[2]: Rs reg_d = words[1].strip() reg_s = words[2].strip() num_reg_d = register_dict.get(reg_d, -1) num_reg_s = register_dict.get(reg_s, -1) if (num_reg_d == -1 or num_reg_s == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_s = '{0:05b}'.format(num_reg_s) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_sub + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_s + '') # Source register self.mif_file.write('0000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def mul_instruct(self, line_index, line): params = line.split(',') if (len(params) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: MUL # words[1]: Rd # words[2]: Rs reg_d = words[1].strip() reg_s = words[2].strip() num_reg_d = register_dict.get(reg_d, -1) num_reg_s = register_dict.get(reg_s, -1) if (num_reg_d == -1 or num_reg_s == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_s = '{0:05b}'.format(num_reg_s) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_mul + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_s + '') # Source register self.mif_file.write('0000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def div_instruct(self, line_index, line): params = line.split(',') if (len(params) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: DIV # words[1]: Rd # words[2]: Rs reg_d = words[1].strip() reg_s = words[2].strip() num_reg_d = register_dict.get(reg_d, -1) num_reg_s = register_dict.get(reg_s, -1) if (num_reg_d == -1 or num_reg_s == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_s = '{0:05b}'.format(num_reg_s) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_div + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_s + '') # Source register self.mif_file.write('0000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def and_instruct(self, line_index, line): params = line.split(',') if (len(params) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: AND # words[1]: Rd # words[2]: Rs reg_d = words[1].strip() reg_s = words[2].strip() num_reg_d = register_dict.get(reg_d, -1) num_reg_s = register_dict.get(reg_s, -1) if (num_reg_d == -1 or num_reg_s == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_s = '{0:05b}'.format(num_reg_s) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_and + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_s + '') # Source register self.mif_file.write('0000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def or_instruct(self, line_index, line): params = line.split(',') if (len(params) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: OR # words[1]: Rd # words[2]: Rs reg_d = words[1].strip() reg_s = words[2].strip() num_reg_d = register_dict.get(reg_d, -1) num_reg_s = register_dict.get(reg_s, -1) if (num_reg_d == -1 or num_reg_s == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_s = '{0:05b}'.format(num_reg_s) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_or + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_s + '') # Source register self.mif_file.write('0000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def cmp_instruct(self, line_index, line): params = line.split(',') if (len(params) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: CMP # words[1]: Rd # words[2]: Rs reg_d = words[1].strip() reg_s = words[2].strip() num_reg_d = register_dict.get(reg_d, -1) num_reg_s = register_dict.get(reg_s, -1) if (num_reg_d == -1 or num_reg_s == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_s = '{0:05b}'.format(num_reg_s) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_cmp + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_s + '') # Source register self.mif_file.write('0000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def not_instruct(self, line_index, line): words = line.split() if (len(words) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: # words[0]: NOT # words[1]: Rd reg_d = words[1] num_reg_d = register_dict.get(reg_d, -1) if (num_reg_d == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_not + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write('000000000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def jr_instruct(self, line_index, line): words = line.split() if (len(words) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: # words[0]: JR # words[1]: Rd reg_d = words[1] num_reg_d = register_dict.get(reg_d, -1) if (num_reg_d == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_jr + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write('000000000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def brfl_instruct(self, line_index, line): params = line.split(',') if (len(params) > 3): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: BRFL # words[1]: LABEL # words[2]: RFlags index # words[3]: Const label = words[1] rflags_index = int(words[2]) const = int(words[3]) address = labels_dict.get(label, -1) if (address == -1): print('erro, label não existe') sys.exit("erro, label não existe") else: bin_address = '{0:016b}'.format(address) bin_rflags_index = '{0:03b}'.format(rflags_index & 0b1111111111111111) bin_const = '{0:01b}'.format(const & 0b1111111111111111) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_brfl + '') # Opcode self.mif_file.write('00000' + '') # Blank space self.mif_file.write(bin_rflags_index + '') # RFlags index self.mif_file.write(bin_const + '') # Const self.mif_file.write('0' + '') # Blank space self.mif_file.write(bin_address + ';') # Label address self.mif_file.write(' -- ' + line + ' //Label address=' + str(address) + '\n') # Original assembly instruction as a comment return def brflr_instruct(self, line_index, line): params = line.split(',') if (len(params) > 3): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: BRFLR # words[1]: Rd # words[2]: RFlags index # words[3]: Const reg_d = words[1] rflags_index = int(words[2]) const = int(words[3]) num_reg_d = register_dict.get(reg_d, -1) if (num_reg_d == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_rflags_index = '{0:03b}'.format(rflags_index & 0b1111111111111111) bin_const = '{0:01b}'.format(const & 0b1111111111111111) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_brflr + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_rflags_index + '') # RFlags index self.mif_file.write(bin_const + '') # Const self.mif_file.write('00000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def call_instruct(self, line_index, line): words = line.split() if (len(words) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: # words[0]: CALL # words[1]: LABEL label = words[1] address = labels_dict.get(label, -1) if (address == -1): print('erro, label não existe') sys.exit("erro, label não existe") else: bin_address = '{0:016b}'.format(address) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_call + '') # Opcode self.mif_file.write('0000000000' + '') # Blank space self.mif_file.write(bin_address + ';') # Label address self.mif_file.write(' -- ' + line + ' //Label address=' + str(address) + '\n') # Original assembly instruction as a comment return def callr_instruct(self, line_index, line): words = line.split() if (len(words) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: # words[0]: CALLR # words[1]: Rd reg_d = words[1] num_reg_d = register_dict.get(reg_d, -1) if (num_reg_d == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_callr + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write('000000000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def ret_instruct(self, line_index, line): words = line.split() if (len(words) > 1): print('erro, operandos demais') sys.exit("erro, operandos demais") else: self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_ret + '') # Opcode self.mif_file.write('00000000000000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def iret_instruct(self, line_index, line): words = line.split() if (len(words) > 1): print('erro, operandos demais') sys.exit("erro, operandos demais") else: self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_iret + '') # Opcode self.mif_file.write('00000000000000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def nop_instruct(self, line_index, line): words = line.split() if (len(words) > 1): print('erro, operandos demais') sys.exit("erro, operandos demais") else: self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_nop + '') # Opcode self.mif_file.write('00000000000000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def jmp_instruct(self, line_index, line): words = line.split() if (len(words) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: # words[0]: JMP # words[1]: LABEL label = words[1] address = labels_dict.get(label, -1) if (address == -1): print('erro, label não existe') sys.exit("erro, label não existe") else: bin_address = '{0:016b}'.format(address) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_jmp + '') # Opcode self.mif_file.write('0000000000' + '') # Blank space self.mif_file.write(bin_address + ';') # Label address self.mif_file.write(' -- ' + line + ' //Label address=' + str(address) + '\n') # Original assembly instruction as a comment return def sprite_id_instruct(self, line_index, line): params = line.split(',') if (len(params) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: SPRITE_ID # words[1]: Rd # words[2]: Rs #print(words) reg_d = words[1].strip() reg_s = words[2].strip() #print(reg_d) #print(reg_s) num_reg_d = register_dict.get(reg_d, -1) num_reg_s = register_dict.get(reg_s, -1) if (num_reg_d == -1 or num_reg_s == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_s = '{0:05b}'.format(num_reg_s) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_sprite_id + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_s + '') # Source register self.mif_file.write('0000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def sprite_color_instruct(self, line_index, line): params = line.split(',') if (len(params) > 2): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: SPRITE_COLOR # words[1]: Rd # words[2]: Rs #print(words) reg_d = words[1].strip() reg_s = words[2].strip() #print(reg_d) #print(reg_s) num_reg_d = register_dict.get(reg_d, -1) num_reg_s = register_dict.get(reg_s, -1) if (num_reg_d == -1 or num_reg_s == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_d = '{0:05b}'.format(num_reg_d) bin_reg_s = '{0:05b}'.format(num_reg_s) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_sprite_color + '') # Opcode self.mif_file.write(bin_reg_d + '') # Destination register self.mif_file.write(bin_reg_s + '') # Source register self.mif_file.write('0000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def sprite_pos_instruct(self, line_index, line): params = line.split(',') if (len(params) > 3): print('erro, operandos demais') sys.exit("erro, operandos demais") else: words = params[0].split() params.remove(params[0]) words.extend(params) # words[0]: SPRITE_POS # words[1]: REG_A # words[2]: REG_B # words[3]: REG_C #print(words) reg_a = words[1].strip() reg_b = words[2].strip() reg_c = words[3].strip() #print(reg_a) #print(reg_b) #print(reg_c) num_reg_a = register_dict.get(reg_a, -1) num_reg_b = register_dict.get(reg_b, -1) num_reg_c = register_dict.get(reg_c, -1) if (num_reg_a == -1 or num_reg_b == -1 or num_reg_c == -1): print('erro, registrador não existe') sys.exit("erro, registrador não existe") else: bin_reg_a = '{0:05b}'.format(num_reg_a) bin_reg_b = '{0:05b}'.format(num_reg_b) bin_reg_c = '{0:05b}'.format(num_reg_c) self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_sprite_pos + '') # Opcode self.mif_file.write(bin_reg_a + '') # Sprite level register self.mif_file.write(bin_reg_b + '') # Sprite row register self.mif_file.write(bin_reg_c + '') # Sprite column register self.mif_file.write('00000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return def sprite_collision_bg_instruct(self, line_index, line): return def sprite_collision_sp_instruct(self, line_index, line): return def wait_vsync_instruct(self, line_index, line): words = line.split() if (len(words) > 1): print('erro, operandos demais') sys.exit("erro, operandos demais") else: self.mif_file.write(str(line_index) + ' : ') # Instruction memory address self.mif_file.write(opcode_wait_vsync + '') # Opcode self.mif_file.write('00000000000000000000000000' + ';') # Blank space self.mif_file.write(' -- ' + line + '\n') # Original assembly instruction as a comment return if __name__ == '__main__': assemblerGUI = AssemblerGUI()