OpenCores
URL https://opencores.org/ocsvn/2d_game_console/2d_game_console/trunk

Subversion Repositories 2d_game_console

[/] [2d_game_console/] [trunk/] [Assembler/] [assembler.py] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 lucas.vbal
#Author: Lucas Alves
2
#License: Public Domain
3
#Assembler
4
 
5
#import string
6
import sys
7
 
8
from tkinter import *
9
from tkinter import filedialog
10
from tkinter import messagebox
11
import os
12
 
13
labels_dict = {}
14
 
15
register_dict = {'R0':0, 'R1':1, 'R2':2, 'R3':3, 'R4':4, 'R5':5, 'R6':6, 'R7':7, 'R8':8, 'R9':9,
16
                 'R10':10, 'R11':11, 'R12':12, 'R13':13, 'R14':14, 'R15':15, 'R16':16, 'R17':17, 'R18':18, 'R19':19,
17
                 'R20':20, 'R21':21, 'R22':22, 'R23':23, 'R24':24, 'R25':25, 'R26':26, 'R27':27, 'R28':28, 'R29':29,
18
                 'R30':30, 'R31':31}
19
 
20
# Interrupt Service Routines labels
21
isr_labels_list = ['.ISR0', '.ISR1', '.ISR2', '.ISR3']
22
 
23
# Number of Interrupt Service Routines
24
isr_num = len(isr_labels_list)
25
 
26
 
27
# INSTRUCTIONS OPERATION CODE #
28
# Graphical instructions
29
opcode_sprite_id            = "110001"
30
opcode_sprite_color         = "110010"
31
opcode_sprite_pos           = "110100"
32
opcode_sprite_collision_bg  = "110101"
33
opcode_sprite_collision_sp  = "110110"
34
opcode_wait_vsync           = "110111"
35
# Arithmetic Instructions
36
opcode_add  = "010001"
37
opcode_sub  = "010010"
38
opcode_mul  = "010100"
39
opcode_div  = "010101"
40
# Logical Instructions
41
opcode_and  = "100001"
42
opcode_or   = "100010"
43
opcode_cmp  = "100100"
44
opcode_not  = "100101"
45
# Control Transfer Instructions (Immediate)
46
opcode_jmp   = "101001"
47
opcode_brfl  = "101010"
48
opcode_call  = "101011"
49
opcode_ret   = "101100"
50
opcode_iret  = "101101"
51
opcode_nop   = "101110"
52
# Control Transfer Instructions (Register)
53
opcode_jr    = "011001"
54
opcode_brflr = "011010"
55
opcode_callr = "011011"
56
# Data Transfer Instructions
57
opcode_lw   = "001001"
58
opcode_sw   = "001010"
59
opcode_limm = "001100"
60
 
61
 
62
class AssemblerGUI:
63
 
64
    # Contructor
65
    def __init__(self):
66
        self.root = Tk()
67
        self.root.title("asm2mif Assembler")
68
        self.root.resizable(False, False)
69
 
70
        memoryFrame = Frame(self.root)
71
        memoryFrame.pack(fill=BOTH)
72
 
73
        memoryLabel = Label(memoryFrame, text="Total size of memory in words")
74
        memoryLabel.pack(side=LEFT, padx=5, pady=5)
75
 
76
        self.memoryEntry = Entry(memoryFrame, width=10)
77
        self.memoryEntry.insert(0, "65536")
78
        self.memoryEntry.pack(side=LEFT, padx=5, pady=5)
79
 
80
        fileLabelFrame = Frame(self.root)
81
        fileLabelFrame.pack(fill=BOTH)
82
 
83
        fileLabel = Label(fileLabelFrame, text="Assembly file:")
84
        fileLabel.pack(side=LEFT, padx=5, pady=0)
85
 
86
        fileFrame = Frame(self.root)
87
        fileFrame.pack(fill=BOTH)
88
 
89
        self.fileEntry = Entry(fileFrame, width=50)
90
        self.fileEntry.pack(side=LEFT, padx=5, pady=0)
91
 
92
        browseButton = Button(fileFrame, text="Browse", fg="black", command=self.ask_open_file)
93
        browseButton.pack(side=LEFT, padx=5, pady=0)
94
 
95
        okFrame = Frame(self.root)
96
        okFrame.pack(fill=BOTH, expand=False)
97
 
98
        okButton = Button(okFrame, text="Save As...", command=self.check_info)
99
        okButton.pack(side=RIGHT, padx=5, pady=5)
100
 
101
        self.root.mainloop()
102
 
103
    def ask_open_file(self):
104
        currdir = os.getcwd()
105
        self.filenameOpened = filedialog.askopenfilename(parent=self.root, initialdir=currdir, title='Open file', filetypes = (("Assembly files","*.asm"),("All files","*.*")))
106
        if len(self.filenameOpened) > 0:
107
            self.fileEntry.delete(0, END)
108
            self.fileEntry.insert(0, self.filenameOpened)
109
 
110
    def ask_save_file(self):
111
        currdir = os.getcwd()
112
        self.filenameSaved = filedialog.asksaveasfilename(parent=self.root, initialdir=currdir, title='Save file', defaultextension='.mif', filetypes = [("Memory Initialization File","*.mif")])
113
        if len(self.filenameSaved) > 0:
114
            self.execute()
115
 
116
    def check_info(self):
117
        self.memorySize = self.memoryEntry.get()
118
        if self.memorySize.isdigit() is True:
119
            self.memorySize = int(self.memorySize)
120
 
121
            self.filenameOpened = self.fileEntry.get()
122
            if os.path.isfile(self.filenameOpened) is True:
123
                self.ask_save_file()
124
            else:
125
                messagebox.showerror(title='Error', message='Please enter a valid input file.')
126
 
127
        else:
128
            messagebox.showerror(title='Error', message='Please enter a valid memory size.')
129
 
130
    def quit(self):
131
        self.root.destroy()
132
        sys.exit()
133
 
134
    def execute(self):
135
        asm_file = open(self.filenameOpened)
136
        original_text = asm_file.readlines()
137
        new_text = list(original_text)
138
        asm_file.close()
139
 
140
        # Removes comments
141
        for line_index, line in enumerate(new_text):
142
            new_text[line_index] = line.strip()
143
            find_index = new_text[line_index].find("//")
144
            if find_index == -1:
145
                continue
146
            elif find_index == 0:
147
                new_text[line_index] = ''
148
            else:
149
                new_text[line_index] = new_text[line_index][:(find_index)]
150
                new_text[line_index] = new_text[line_index].strip()
151
 
152
        # Removes empty elements
153
        new_text = list(filter(lambda x : x != '', new_text))
154
 
155
        # Removes lines with labels and saves address
156
        for line_index, line in enumerate(new_text, isr_num):
157
            find_index = line.find(":")
158
            if find_index == -1:
159
                continue
160
            elif find_index == 0:
161
                messagebox.showerror(title='Error', message='Unamed label at address {}.'.format(line_index))
162
                self.quit()
163
            else:
164
                label = line[:(find_index)]
165
                if label in labels_dict:
166
                    messagebox.showerror(title='Error', message='Label "{}" repeated at address {}.'.format(label, line_index))
167
                    self.quit()
168
                else:
169
                    labels_dict[label] = line_index
170
                    new_text.pop(line_index - isr_num)
171
 
172
        #print (labels_dict.items())
173
 
174
        #for index2, line2 in enumerate(new_text):
175
        #    print (index2, line2)
176
 
177
 
178
        self.mif_file = open(self.filenameSaved, 'w')
179
 
180
        self.mif_file.write('DEPTH = ' + str(self.memorySize) + ';          -- The size of memory in words\n')
181
        self.mif_file.write('WIDTH = 32;             -- The size of data in bits\n')
182
        self.mif_file.write('ADDRESS_RADIX = UNS;    -- The radix for address values\n')
183
        self.mif_file.write('DATA_RADIX = BIN;       -- The radix for data values\n')
184
        self.mif_file.write('CONTENT                 -- Start of (address : data pairs)\n')
185
        self.mif_file.write('BEGIN\n\n')
186
 
187
        # Search for Interrupt Service Routines labels on labels_dict dictionary
188
        for index, isr_label in enumerate(isr_labels_list):
189
 
190
            self.mif_file.write(str(index) + ' : ') # Instruction memory address
191
 
192
            if isr_label in labels_dict:
193
                address = labels_dict.get(isr_label, -1)
194
 
195
                if (address == -1):
196
                    print('erro, label não existe')
197
                    sys.exit("erro, label não existe")
198
                else:
199
                    bin_address = '{0:016b}'.format(address)
200
 
201
                    self.mif_file.write(opcode_jmp + '')         # JMP Opcode
202
                    self.mif_file.write('0000000000' + '')       # Blank space
203
                    self.mif_file.write(bin_address + ';')       # Label address
204
                    self.mif_file.write('    -- ' + isr_label + ': JMP ' + str(address) + '\n')    # Assembly instruction as a comment
205
            else:
206
                self.mif_file.write(opcode_iret + '')                    # RET Opcode
207
                self.mif_file.write('00000000000000000000000000' + ';')  # Blank space
208
                self.mif_file.write('    -- ' + isr_label + ': IRET \n') # Assembly instruction as a comment
209
 
210
        # Identifies instruction and calls corresponding function
211
        for line_index, line in enumerate(new_text, isr_num):
212
 
213
            #print (line_index, line)
214
 
215
            words = line.split()
216
            if words[0] == "LW":
217
                self.lw_instruct(line_index, line)
218
 
219
            elif words[0] == "SW":
220
                self.sw_instruct(line_index, line)
221
 
222
            elif words[0] == "LIMM":
223
                self.limm_instruct(line_index, line)
224
 
225
            elif words[0] == "ADD":
226
                self.add_instruct(line_index, line)
227
 
228
            elif words[0] == "SUB":
229
                self.sub_instruct(line_index, line)
230
 
231
            elif words[0] == "MUL":
232
                self.mul_instruct(line_index, line)
233
 
234
            elif words[0] == "DIV":
235
                self.div_instruct(line_index, line)
236
 
237
            elif words[0] == "AND":
238
                self.and_instruct(line_index, line)
239
 
240
            elif words[0] == "OR":
241
                self.or_instruct(line_index, line)
242
 
243
            elif words[0] == "CMP":
244
                self.cmp_instruct(line_index, line)
245
 
246
            elif words[0] == "NOT":
247
                self.not_instruct(line_index, line)
248
 
249
            elif words[0] == "JR":
250
                self.jr_instruct(line_index, line)
251
 
252
            elif words[0] == "BRFL":
253
                self.brfl_instruct(line_index, line)
254
 
255
            elif words[0] == "BRFLR":
256
                self.brflr_instruct(line_index, line)
257
 
258
            elif words[0] == "CALL":
259
                self.call_instruct(line_index, line)
260
 
261
            elif words[0] == "CALLR":
262
                self.callr_instruct(line_index, line)
263
 
264
            elif words[0] == "RET":
265
                self.ret_instruct(line_index, line)
266
 
267
            elif words[0] == "IRET":
268
                self.iret_instruct(line_index, line)
269
 
270
            elif words[0] == "NOP":
271
                self.nop_instruct(line_index, line)
272
 
273
            elif words[0] == "JMP":
274
                self.jmp_instruct(line_index, line)
275
 
276
            elif words[0] == "SPRITE_ID":
277
                self.sprite_id_instruct(line_index, line)
278
 
279
            elif words[0] == "SPRITE_COLOR":
280
                self.sprite_color_instruct(line_index, line)
281
 
282
            elif words[0] == "SPRITE_POS":
283
                self.sprite_pos_instruct(line_index, line)
284
 
285
            elif words[0] == "SPRITE_COLLISION_BG":
286
                self.sprite_collision_bg_instruct(line_index, line)
287
 
288
            elif words[0] == "SPRITE_COLLISION_SP":
289
                self.sprite_collision_sp_instruct(line_index, line)
290
 
291
            elif words[0] == "WAIT_VSYNC":
292
                self.wait_vsync_instruct(line_index, line)
293
 
294
            else:
295
                messagebox.showerror(title='Error', message='"{}" instruction at address {} does not exist.'.format(words[0], line_index))
296
                self.quit()
297
 
298
        self.mif_file.write('[' + str(line_index+1) + '..' + str(self.memorySize-1) + '] : 00000000000000000000000000000000;\n')
299
        self.mif_file.write('END;')
300
        self.mif_file.close()
301
 
302
        messagebox.showinfo(parent=self.root, title='Info', message='Done!')
303
 
304
        self.quit()
305
 
306
    def lw_instruct(self, line_index, line):
307
        params = line.split(',')
308
 
309
        # params[0]: LW Rd
310
        # params[1]: Imm(Rb) or (Rb)
311
 
312
        if (len(params) != 2):
313
            print('erro, número de operandos errado')
314
            sys.exit("erro, número de operandos errado")
315
        else:
316
            words = params[0].split()
317
            params.remove(params[0])
318
            words.extend(params)
319
 
320
            # words[0]: LW
321
            # words[1]: Rd
322
            # words[2]: Imm(Rb) or (Rb)
323
 
324
            #print(words) #################################
325
 
326
            if (len(words) != 3):
327
                print('erro, número de operandos errado')
328
                sys.exit("erro, número de operandos errado")
329
            else:
330
                words[2] = words[2].strip()
331
 
332
                #print(words) #################################
333
 
334
                # Addressing Mode: Register
335
                if words[2][0] == '(':
336
                    words[2] = words[2].strip('(')
337
                    words[2] = words[2].strip(')')
338
                    words[2] = words[2].strip()
339
 
340
                    # words[0]: LW
341
                    # words[1]: Rd
342
                    # words[2]: Rb
343
 
344
                    #print(words) #################################
345
 
346
                    reg_d = words[1]
347
                    reg_b = words[2]
348
                    num_reg_d = register_dict.get(reg_d, -1)
349
                    num_reg_b = register_dict.get(reg_b, -1)
350
 
351
                    if (num_reg_d == -1 or num_reg_b == -1):
352
                        print('erro, registrador não existe')
353
                        sys.exit("erro, registrador não existe")
354
                    else:
355
                        bin_reg_d = '{0:05b}'.format(num_reg_d)
356
                        bin_reg_b = '{0:05b}'.format(num_reg_b)
357
 
358
                        self.mif_file.write(str(line_index) + ' : ') # Instruction memory address
359
                        self.mif_file.write(opcode_lw + '')          # Opcode
360
                        self.mif_file.write(bin_reg_d + '')          # Destination register
361
                        self.mif_file.write(bin_reg_b + '')          # Source register
362
                        self.mif_file.write('0000000000000000;')     # Blank space
363
                        self.mif_file.write('    -- ' + line + '\n') # Original assembly instruction as a comment
364
 
365
                # Addressing Mode: Base-Offset
366
                else:
367
                    params = words[2].split('(')
368
                    words.remove(words[2])
369
                    words.extend(params)
370
 
371
                    #print(words) #################################
372
 
373
                    # Addressing Mode: Base-Offset
374
                    if(len(words) == 4):
375
                        words[2] = words[2].strip()
376
                        words[3] = words[3].strip(')')
377
                        words[3] = words[3].strip()
378
 
379
                        # words[0]: LW
380
                        # words[1]: Rd
381
                        # words[2]: Imm
382
                        # words[3]: Rb
383
 
384
                        #print(words) #################################
385
 
386
                        reg_d = words[1]
387
                        imm = int(words[2])
388
                        reg_b = words[3]
389
                        num_reg_d = register_dict.get(reg_d, -1)
390
                        num_reg_b = register_dict.get(reg_b, -1)
391
 
392
                        if (num_reg_d == -1 or num_reg_b == -1):
393
                            print('erro, registrador não existe')
394
                            sys.exit("erro, registrador não existe")
395
                        else:
396
                            bin_reg_d = '{0:05b}'.format(num_reg_d)
397
                            bin_reg_b = '{0:05b}'.format(num_reg_b)
398
                            bin_imm = '{0:016b}'.format(imm & 0b1111111111111111)
399
 
400
                            self.mif_file.write(str(line_index) + ' : ') # Instruction memory address
401
                            self.mif_file.write(opcode_lw + '')          # Opcode
402
                            self.mif_file.write(bin_reg_d + '')          # Destination register
403
                            self.mif_file.write(bin_reg_b + '')          # Source register
404
                            self.mif_file.write(bin_imm + ';')           # Immediate value
405
                            self.mif_file.write('    -- ' + line + '\n') # Original assembly instruction as a comment
406
 
407
                    else:
408
                        print('erro, número de operandos errado')
409
                        sys.exit("erro, número de operandos errado")
410
        return
411
 
412
    def sw_instruct(self, line_index, line):
413
        params = line.split(',')
414
 
415
        # params[0]: SW Rd
416
        # params[1]: Imm(Rb) or (Rb)
417
 
418
        if (len(params) != 2):
419
            print('erro, número de operandos errado')
420
            sys.exit("erro, número de operandos errado")
421
        else:
422
            words = params[0].split()
423
            params.remove(params[0])
424
            words.extend(params)
425
 
426
            # words[0]: SW
427
            # words[1]: Rd
428
            # words[2]: Imm(Rb) or (Rb)
429
 
430
            #print(words) #################################
431
 
432
            if (len(words) != 3):
433
                print('erro, número de operandos errado')
434
                sys.exit("erro, número de operandos errado")
435
            else:
436
                words[2] = words[2].strip()
437
 
438
                #print(words) #################################
439
 
440
                # Addressing Mode: Register
441
                if words[2][0] == '(':
442
                    words[2] = words[2].strip('(')
443
                    words[2] = words[2].strip(')')
444
                    words[2] = words[2].strip()
445
 
446
                    # words[0]: SW
447
                    # words[1]: Rd
448
                    # words[2]: Rb
449
 
450
                    #print(words) #################################
451
 
452
                    reg_d = words[1]
453
                    reg_b = words[2]
454
                    num_reg_d = register_dict.get(reg_d, -1)
455
                    num_reg_b = register_dict.get(reg_b, -1)
456
 
457
                    if (num_reg_d == -1 or num_reg_b == -1):
458
                        print('erro, registrador não existe')
459
                        sys.exit("erro, registrador não existe")
460
                    else:
461
                        bin_reg_d = '{0:05b}'.format(num_reg_d)
462
                        bin_reg_b = '{0:05b}'.format(num_reg_b)
463
 
464
                        self.mif_file.write(str(line_index) + ' : ') # Instruction memory address
465
                        self.mif_file.write(opcode_sw + '')          # Opcode
466
                        self.mif_file.write(bin_reg_d + '')          # Destination register
467
                        self.mif_file.write(bin_reg_b + '')          # Source register
468
                        self.mif_file.write('0000000000000000;')     # Blank space
469
                        self.mif_file.write('    -- ' + line + '\n') # Original assembly instruction as a comment
470
 
471
                # Addressing Mode: Base-Offset
472
                else:
473
                    params = words[2].split('(')
474
                    words.remove(words[2])
475
                    words.extend(params)
476
 
477
                    #print(words) #################################
478
 
479
                    # Addressing Mode: Base-Offset
480
                    if(len(words) == 4):
481
                        words[2] = words[2].strip()
482
                        words[3] = words[3].strip(')')
483
                        words[3] = words[3].strip()
484
 
485
                        # words[0]: SW
486
                        # words[1]: Rd
487
                        # words[2]: Imm
488
                        # words[3]: Rb
489
 
490
                        #print(words) #################################
491
 
492
                        reg_d = words[1]
493
                        imm = int(words[2])
494
                        reg_b = words[3]
495
                        num_reg_d = register_dict.get(reg_d, -1)
496
                        num_reg_b = register_dict.get(reg_b, -1)
497
 
498
                        if (num_reg_d == -1 or num_reg_b == -1):
499
                            print('erro, registrador não existe')
500
                            sys.exit("erro, registrador não existe")
501
                        else:
502
                            bin_reg_d = '{0:05b}'.format(num_reg_d)
503
                            bin_reg_b = '{0:05b}'.format(num_reg_b)
504
                            bin_imm = '{0:016b}'.format(imm & 0b1111111111111111)
505
 
506
                            self.mif_file.write(str(line_index) + ' : ') # Instruction memory address
507
                            self.mif_file.write(opcode_sw + '')          # Opcode
508
                            self.mif_file.write(bin_reg_d + '')          # Destination register
509
                            self.mif_file.write(bin_reg_b + '')          # Source register
510
                            self.mif_file.write(bin_imm + ';')           # Immediate value
511
                            self.mif_file.write('    -- ' + line + '\n') # Original assembly instruction as a comment
512
 
513
                    else:
514
                        print('erro, número de operandos errado')
515
                        sys.exit("erro, número de operandos errado")
516
        return
517
 
518
    def limm_instruct(self, line_index, line):
519
        params = line.split(',')
520
 
521
        # params[0]: LIMM Rd
522
        # params[1]: Imm
523
 
524
        if (len(params) != 2):
525
            print('erro, número de operandos errado')
526
            sys.exit("erro, número de operandos errado")
527
        else:
528
            words = params[0].split()
529
            params.remove(params[0])
530
            words.extend(params)
531
            words[2] = words[2].strip()
532
 
533
            # words[0]: LIMM
534
            # words[1]: Rd
535
            # words[2]: Imm
536
 
537
            if (len(words) != 3):
538
                print('erro, número de operandos errado')
539
                sys.exit("erro, número de operandos errado")
540
            else:
541
                reg_d = words[1]
542
                imm = int(words[2])
543
                num_reg_d = register_dict.get(reg_d, -1)
544
 
545
                if (num_reg_d == -1):
546
                    print('erro, registrador não existe')
547
                    sys.exit("erro, registrador não existe")
548
                else:
549
                    bin_reg_d = '{0:05b}'.format(num_reg_d)
550
                    bin_imm = '{0:016b}'.format(imm & 0b1111111111111111)
551
 
552
                    self.mif_file.write(str(line_index) + ' : ') # Instruction memory address
553
                    self.mif_file.write(opcode_limm + '')        # Opcode
554
                    self.mif_file.write(bin_reg_d + '')          # Destination register
555
                    self.mif_file.write('00000' + '')            # Blank space
556
                    self.mif_file.write(bin_imm + ';')           # Immediate value
557
                    self.mif_file.write('    -- ' + line + '\n') # Original assembly instruction as a comment
558
        return
559
 
560
    def add_instruct(self, line_index, line):
561
        params = line.split(',')
562
 
563
        if (len(params) > 2):
564
            print('erro, operandos demais')
565
            sys.exit("erro, operandos demais")
566
        else:
567
            words = params[0].split()
568
            params.remove(params[0])
569
            words.extend(params)
570
 
571
            # words[0]: ADD
572
            # words[1]: Rd
573
            # words[2]: Rs
574
 
575
            reg_d = words[1].strip()
576
            reg_s = words[2].strip()
577
 
578
            num_reg_d = register_dict.get(reg_d, -1)
579
            num_reg_s = register_dict.get(reg_s, -1)
580
 
581
            if (num_reg_d == -1 or num_reg_s == -1):
582
                print('erro, registrador não existe')
583
                sys.exit("erro, registrador não existe")
584
            else:
585
                bin_reg_d = '{0:05b}'.format(num_reg_d)
586
                bin_reg_s = '{0:05b}'.format(num_reg_s)
587
 
588
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
589
                self.mif_file.write(opcode_add + '')            # Opcode
590
                self.mif_file.write(bin_reg_d + '')             # Destination register
591
                self.mif_file.write(bin_reg_s + '')             # Source register
592
                self.mif_file.write('0000000000000000' + ';')   # Blank space
593
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
594
        return
595
 
596
    def sub_instruct(self, line_index, line):
597
        params = line.split(',')
598
 
599
        if (len(params) > 2):
600
            print('erro, operandos demais')
601
            sys.exit("erro, operandos demais")
602
        else:
603
            words = params[0].split()
604
            params.remove(params[0])
605
            words.extend(params)
606
 
607
            # words[0]: SUB
608
            # words[1]: Rd
609
            # words[2]: Rs
610
 
611
            reg_d = words[1].strip()
612
            reg_s = words[2].strip()
613
 
614
            num_reg_d = register_dict.get(reg_d, -1)
615
            num_reg_s = register_dict.get(reg_s, -1)
616
 
617
            if (num_reg_d == -1 or num_reg_s == -1):
618
                print('erro, registrador não existe')
619
                sys.exit("erro, registrador não existe")
620
            else:
621
                bin_reg_d = '{0:05b}'.format(num_reg_d)
622
                bin_reg_s = '{0:05b}'.format(num_reg_s)
623
 
624
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
625
                self.mif_file.write(opcode_sub + '')            # Opcode
626
                self.mif_file.write(bin_reg_d + '')             # Destination register
627
                self.mif_file.write(bin_reg_s + '')             # Source register
628
                self.mif_file.write('0000000000000000' + ';')   # Blank space
629
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
630
        return
631
 
632
    def mul_instruct(self, line_index, line):
633
        params = line.split(',')
634
 
635
        if (len(params) > 2):
636
            print('erro, operandos demais')
637
            sys.exit("erro, operandos demais")
638
        else:
639
            words = params[0].split()
640
            params.remove(params[0])
641
            words.extend(params)
642
 
643
            # words[0]: MUL
644
            # words[1]: Rd
645
            # words[2]: Rs
646
 
647
            reg_d = words[1].strip()
648
            reg_s = words[2].strip()
649
 
650
            num_reg_d = register_dict.get(reg_d, -1)
651
            num_reg_s = register_dict.get(reg_s, -1)
652
 
653
            if (num_reg_d == -1 or num_reg_s == -1):
654
                print('erro, registrador não existe')
655
                sys.exit("erro, registrador não existe")
656
            else:
657
                bin_reg_d = '{0:05b}'.format(num_reg_d)
658
                bin_reg_s = '{0:05b}'.format(num_reg_s)
659
 
660
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
661
                self.mif_file.write(opcode_mul + '')            # Opcode
662
                self.mif_file.write(bin_reg_d + '')             # Destination register
663
                self.mif_file.write(bin_reg_s + '')             # Source register
664
                self.mif_file.write('0000000000000000' + ';')   # Blank space
665
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
666
        return
667
 
668
    def div_instruct(self, line_index, line):
669
        params = line.split(',')
670
 
671
        if (len(params) > 2):
672
            print('erro, operandos demais')
673
            sys.exit("erro, operandos demais")
674
        else:
675
            words = params[0].split()
676
            params.remove(params[0])
677
            words.extend(params)
678
 
679
            # words[0]: DIV
680
            # words[1]: Rd
681
            # words[2]: Rs
682
 
683
            reg_d = words[1].strip()
684
            reg_s = words[2].strip()
685
 
686
            num_reg_d = register_dict.get(reg_d, -1)
687
            num_reg_s = register_dict.get(reg_s, -1)
688
 
689
            if (num_reg_d == -1 or num_reg_s == -1):
690
                print('erro, registrador não existe')
691
                sys.exit("erro, registrador não existe")
692
            else:
693
                bin_reg_d = '{0:05b}'.format(num_reg_d)
694
                bin_reg_s = '{0:05b}'.format(num_reg_s)
695
 
696
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
697
                self.mif_file.write(opcode_div + '')            # Opcode
698
                self.mif_file.write(bin_reg_d + '')             # Destination register
699
                self.mif_file.write(bin_reg_s + '')             # Source register
700
                self.mif_file.write('0000000000000000' + ';')   # Blank space
701
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
702
        return
703
 
704
    def and_instruct(self, line_index, line):
705
        params = line.split(',')
706
 
707
        if (len(params) > 2):
708
            print('erro, operandos demais')
709
            sys.exit("erro, operandos demais")
710
        else:
711
            words = params[0].split()
712
            params.remove(params[0])
713
            words.extend(params)
714
 
715
            # words[0]: AND
716
            # words[1]: Rd
717
            # words[2]: Rs
718
 
719
            reg_d = words[1].strip()
720
            reg_s = words[2].strip()
721
 
722
            num_reg_d = register_dict.get(reg_d, -1)
723
            num_reg_s = register_dict.get(reg_s, -1)
724
 
725
            if (num_reg_d == -1 or num_reg_s == -1):
726
                print('erro, registrador não existe')
727
                sys.exit("erro, registrador não existe")
728
            else:
729
                bin_reg_d = '{0:05b}'.format(num_reg_d)
730
                bin_reg_s = '{0:05b}'.format(num_reg_s)
731
 
732
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
733
                self.mif_file.write(opcode_and + '')            # Opcode
734
                self.mif_file.write(bin_reg_d + '')             # Destination register
735
                self.mif_file.write(bin_reg_s + '')             # Source register
736
                self.mif_file.write('0000000000000000' + ';')   # Blank space
737
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
738
        return
739
 
740
    def or_instruct(self, line_index, line):
741
        params = line.split(',')
742
 
743
        if (len(params) > 2):
744
            print('erro, operandos demais')
745
            sys.exit("erro, operandos demais")
746
        else:
747
            words = params[0].split()
748
            params.remove(params[0])
749
            words.extend(params)
750
 
751
            # words[0]: OR
752
            # words[1]: Rd
753
            # words[2]: Rs
754
 
755
            reg_d = words[1].strip()
756
            reg_s = words[2].strip()
757
 
758
            num_reg_d = register_dict.get(reg_d, -1)
759
            num_reg_s = register_dict.get(reg_s, -1)
760
 
761
            if (num_reg_d == -1 or num_reg_s == -1):
762
                print('erro, registrador não existe')
763
                sys.exit("erro, registrador não existe")
764
            else:
765
                bin_reg_d = '{0:05b}'.format(num_reg_d)
766
                bin_reg_s = '{0:05b}'.format(num_reg_s)
767
 
768
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
769
                self.mif_file.write(opcode_or + '')             # Opcode
770
                self.mif_file.write(bin_reg_d + '')             # Destination register
771
                self.mif_file.write(bin_reg_s + '')             # Source register
772
                self.mif_file.write('0000000000000000' + ';')   # Blank space
773
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
774
        return
775
 
776
    def cmp_instruct(self, line_index, line):
777
        params = line.split(',')
778
 
779
        if (len(params) > 2):
780
            print('erro, operandos demais')
781
            sys.exit("erro, operandos demais")
782
        else:
783
            words = params[0].split()
784
            params.remove(params[0])
785
            words.extend(params)
786
 
787
            # words[0]: CMP
788
            # words[1]: Rd
789
            # words[2]: Rs
790
 
791
            reg_d = words[1].strip()
792
            reg_s = words[2].strip()
793
 
794
            num_reg_d = register_dict.get(reg_d, -1)
795
            num_reg_s = register_dict.get(reg_s, -1)
796
 
797
            if (num_reg_d == -1 or num_reg_s == -1):
798
                print('erro, registrador não existe')
799
                sys.exit("erro, registrador não existe")
800
            else:
801
                bin_reg_d = '{0:05b}'.format(num_reg_d)
802
                bin_reg_s = '{0:05b}'.format(num_reg_s)
803
 
804
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
805
                self.mif_file.write(opcode_cmp + '')            # Opcode
806
                self.mif_file.write(bin_reg_d + '')             # Destination register
807
                self.mif_file.write(bin_reg_s + '')             # Source register
808
                self.mif_file.write('0000000000000000' + ';')   # Blank space
809
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
810
        return
811
 
812
    def not_instruct(self, line_index, line):
813
        words = line.split()
814
        if (len(words) > 2):
815
            print('erro, operandos demais')
816
            sys.exit("erro, operandos demais")
817
        else:
818
 
819
            # words[0]: NOT
820
            # words[1]: Rd
821
 
822
            reg_d = words[1]
823
            num_reg_d = register_dict.get(reg_d, -1)
824
 
825
            if (num_reg_d == -1):
826
                print('erro, registrador não existe')
827
                sys.exit("erro, registrador não existe")
828
            else:
829
                bin_reg_d = '{0:05b}'.format(num_reg_d)
830
 
831
                self.mif_file.write(str(line_index) + ' : ')        # Instruction memory address
832
                self.mif_file.write(opcode_not + '')                # Opcode
833
                self.mif_file.write(bin_reg_d + '')                 # Destination register
834
                self.mif_file.write('000000000000000000000' + ';')  # Blank space
835
                self.mif_file.write('    -- ' + line + '\n')        # Original assembly instruction as a comment
836
        return
837
 
838
    def jr_instruct(self, line_index, line):
839
        words = line.split()
840
        if (len(words) > 2):
841
            print('erro, operandos demais')
842
            sys.exit("erro, operandos demais")
843
        else:
844
 
845
            # words[0]: JR
846
            # words[1]: Rd
847
 
848
            reg_d = words[1]
849
            num_reg_d = register_dict.get(reg_d, -1)
850
 
851
            if (num_reg_d == -1):
852
                print('erro, registrador não existe')
853
                sys.exit("erro, registrador não existe")
854
            else:
855
                bin_reg_d = '{0:05b}'.format(num_reg_d)
856
 
857
                self.mif_file.write(str(line_index) + ' : ')        # Instruction memory address
858
                self.mif_file.write(opcode_jr + '')                 # Opcode
859
                self.mif_file.write(bin_reg_d + '')                 # Destination register
860
                self.mif_file.write('000000000000000000000' + ';')  # Blank space
861
                self.mif_file.write('    -- ' + line + '\n')        # Original assembly instruction as a comment
862
        return
863
 
864
    def brfl_instruct(self, line_index, line):
865
        params = line.split(',')
866
 
867
        if (len(params) > 3):
868
            print('erro, operandos demais')
869
            sys.exit("erro, operandos demais")
870
        else:
871
            words = params[0].split()
872
            params.remove(params[0])
873
            words.extend(params)
874
 
875
            # words[0]: BRFL
876
            # words[1]: LABEL
877
            # words[2]: RFlags index
878
            # words[3]: Const
879
 
880
            label = words[1]
881
            rflags_index = int(words[2])
882
            const = int(words[3])
883
 
884
            address = labels_dict.get(label, -1)
885
            if (address == -1):
886
                print('erro, label não existe')
887
                sys.exit("erro, label não existe")
888
            else:
889
                bin_address = '{0:016b}'.format(address)
890
                bin_rflags_index = '{0:03b}'.format(rflags_index & 0b1111111111111111)
891
                bin_const = '{0:01b}'.format(const & 0b1111111111111111)
892
 
893
                self.mif_file.write(str(line_index) + ' : ') # Instruction memory address
894
                self.mif_file.write(opcode_brfl + '')        # Opcode
895
                self.mif_file.write('00000' + '')            # Blank space
896
                self.mif_file.write(bin_rflags_index + '')   # RFlags index
897
                self.mif_file.write(bin_const + '')          # Const
898
                self.mif_file.write('0' + '')                # Blank space
899
                self.mif_file.write(bin_address + ';')       # Label address
900
                self.mif_file.write('    -- ' + line + ' //Label address=' + str(address) + '\n')    # Original assembly instruction as a comment
901
        return
902
 
903
 
904
    def brflr_instruct(self, line_index, line):
905
        params = line.split(',')
906
 
907
        if (len(params) > 3):
908
            print('erro, operandos demais')
909
            sys.exit("erro, operandos demais")
910
        else:
911
            words = params[0].split()
912
            params.remove(params[0])
913
            words.extend(params)
914
 
915
            # words[0]: BRFLR
916
            # words[1]: Rd
917
            # words[2]: RFlags index
918
            # words[3]: Const
919
 
920
            reg_d = words[1]
921
            rflags_index = int(words[2])
922
            const = int(words[3])
923
 
924
            num_reg_d = register_dict.get(reg_d, -1)
925
            if (num_reg_d == -1):
926
                print('erro, registrador não existe')
927
                sys.exit("erro, registrador não existe")
928
            else:
929
                bin_reg_d = '{0:05b}'.format(num_reg_d)
930
                bin_rflags_index = '{0:03b}'.format(rflags_index & 0b1111111111111111)
931
                bin_const = '{0:01b}'.format(const & 0b1111111111111111)
932
 
933
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
934
                self.mif_file.write(opcode_brflr + '')          # Opcode
935
                self.mif_file.write(bin_reg_d + '')             # Destination register
936
                self.mif_file.write(bin_rflags_index + '')      # RFlags index
937
                self.mif_file.write(bin_const + '')             # Const
938
                self.mif_file.write('00000000000000000' + ';')  # Blank space
939
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
940
        return
941
 
942
    def call_instruct(self, line_index, line):
943
        words = line.split()
944
        if (len(words) > 2):
945
            print('erro, operandos demais')
946
            sys.exit("erro, operandos demais")
947
        else:
948
 
949
            # words[0]: CALL
950
            # words[1]: LABEL
951
 
952
            label = words[1]
953
            address = labels_dict.get(label, -1)
954
            if (address == -1):
955
                print('erro, label não existe')
956
                sys.exit("erro, label não existe")
957
            else:
958
                bin_address = '{0:016b}'.format(address)
959
 
960
                self.mif_file.write(str(line_index) + ' : ') # Instruction memory address
961
                self.mif_file.write(opcode_call + '')        # Opcode
962
                self.mif_file.write('0000000000' + '')       # Blank space
963
                self.mif_file.write(bin_address + ';')       # Label address
964
                self.mif_file.write('    -- ' + line + ' //Label address=' + str(address) + '\n')    # Original assembly instruction as a comment
965
        return
966
 
967
    def callr_instruct(self, line_index, line):
968
        words = line.split()
969
        if (len(words) > 2):
970
            print('erro, operandos demais')
971
            sys.exit("erro, operandos demais")
972
        else:
973
 
974
            # words[0]: CALLR
975
            # words[1]: Rd
976
 
977
            reg_d = words[1]
978
            num_reg_d = register_dict.get(reg_d, -1)
979
 
980
            if (num_reg_d == -1):
981
                print('erro, registrador não existe')
982
                sys.exit("erro, registrador não existe")
983
            else:
984
                bin_reg_d = '{0:05b}'.format(num_reg_d)
985
 
986
                self.mif_file.write(str(line_index) + ' : ')        # Instruction memory address
987
                self.mif_file.write(opcode_callr + '')              # Opcode
988
                self.mif_file.write(bin_reg_d + '')                 # Destination register
989
                self.mif_file.write('000000000000000000000' + ';')  # Blank space
990
                self.mif_file.write('    -- ' + line + '\n')        # Original assembly instruction as a comment
991
        return
992
 
993
    def ret_instruct(self, line_index, line):
994
        words = line.split()
995
        if (len(words) > 1):
996
            print('erro, operandos demais')
997
            sys.exit("erro, operandos demais")
998
        else:
999
            self.mif_file.write(str(line_index) + ' : ')            # Instruction memory address
1000
            self.mif_file.write(opcode_ret + '')                    # Opcode
1001
            self.mif_file.write('00000000000000000000000000' + ';') # Blank space
1002
            self.mif_file.write('    -- ' + line + '\n')            # Original assembly instruction as a comment
1003
        return
1004
 
1005
    def iret_instruct(self, line_index, line):
1006
        words = line.split()
1007
        if (len(words) > 1):
1008
            print('erro, operandos demais')
1009
            sys.exit("erro, operandos demais")
1010
        else:
1011
            self.mif_file.write(str(line_index) + ' : ')            # Instruction memory address
1012
            self.mif_file.write(opcode_iret + '')                   # Opcode
1013
            self.mif_file.write('00000000000000000000000000' + ';') # Blank space
1014
            self.mif_file.write('    -- ' + line + '\n')            # Original assembly instruction as a comment
1015
        return
1016
 
1017
    def nop_instruct(self, line_index, line):
1018
        words = line.split()
1019
        if (len(words) > 1):
1020
            print('erro, operandos demais')
1021
            sys.exit("erro, operandos demais")
1022
        else:
1023
            self.mif_file.write(str(line_index) + ' : ')            # Instruction memory address
1024
            self.mif_file.write(opcode_nop + '')                    # Opcode
1025
            self.mif_file.write('00000000000000000000000000' + ';') # Blank space
1026
            self.mif_file.write('    -- ' + line + '\n')            # Original assembly instruction as a comment
1027
        return
1028
 
1029
    def jmp_instruct(self, line_index, line):
1030
        words = line.split()
1031
        if (len(words) > 2):
1032
            print('erro, operandos demais')
1033
            sys.exit("erro, operandos demais")
1034
        else:
1035
 
1036
            # words[0]: JMP
1037
            # words[1]: LABEL
1038
 
1039
            label = words[1]
1040
            address = labels_dict.get(label, -1)
1041
 
1042
            if (address == -1):
1043
                print('erro, label não existe')
1044
                sys.exit("erro, label não existe")
1045
            else:
1046
                bin_address = '{0:016b}'.format(address)
1047
 
1048
                self.mif_file.write(str(line_index) + ' : ') # Instruction memory address
1049
                self.mif_file.write(opcode_jmp + '')         # Opcode
1050
                self.mif_file.write('0000000000' + '')       # Blank space
1051
                self.mif_file.write(bin_address + ';')       # Label address
1052
                self.mif_file.write('    -- ' + line + ' //Label address=' + str(address) + '\n')    # Original assembly instruction as a comment
1053
        return
1054
 
1055
    def sprite_id_instruct(self, line_index, line):
1056
        params = line.split(',')
1057
 
1058
        if (len(params) > 2):
1059
            print('erro, operandos demais')
1060
            sys.exit("erro, operandos demais")
1061
        else:
1062
            words = params[0].split()
1063
            params.remove(params[0])
1064
            words.extend(params)
1065
 
1066
            # words[0]: SPRITE_ID
1067
            # words[1]: Rd
1068
            # words[2]: Rs
1069
 
1070
            #print(words)
1071
 
1072
            reg_d = words[1].strip()
1073
            reg_s = words[2].strip()
1074
 
1075
            #print(reg_d)
1076
            #print(reg_s)
1077
 
1078
            num_reg_d = register_dict.get(reg_d, -1)
1079
            num_reg_s = register_dict.get(reg_s, -1)
1080
 
1081
            if (num_reg_d == -1 or num_reg_s == -1):
1082
                print('erro, registrador não existe')
1083
                sys.exit("erro, registrador não existe")
1084
            else:
1085
                bin_reg_d = '{0:05b}'.format(num_reg_d)
1086
                bin_reg_s = '{0:05b}'.format(num_reg_s)
1087
 
1088
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
1089
                self.mif_file.write(opcode_sprite_id + '')      # Opcode
1090
                self.mif_file.write(bin_reg_d + '')             # Destination register
1091
                self.mif_file.write(bin_reg_s + '')             # Source register
1092
                self.mif_file.write('0000000000000000' + ';')   # Blank space
1093
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
1094
        return
1095
 
1096
    def sprite_color_instruct(self, line_index, line):
1097
        params = line.split(',')
1098
 
1099
        if (len(params) > 2):
1100
            print('erro, operandos demais')
1101
            sys.exit("erro, operandos demais")
1102
        else:
1103
            words = params[0].split()
1104
            params.remove(params[0])
1105
            words.extend(params)
1106
 
1107
            # words[0]: SPRITE_COLOR
1108
            # words[1]: Rd
1109
            # words[2]: Rs
1110
 
1111
            #print(words)
1112
 
1113
            reg_d = words[1].strip()
1114
            reg_s = words[2].strip()
1115
 
1116
            #print(reg_d)
1117
            #print(reg_s)
1118
 
1119
            num_reg_d = register_dict.get(reg_d, -1)
1120
            num_reg_s = register_dict.get(reg_s, -1)
1121
 
1122
            if (num_reg_d == -1 or num_reg_s == -1):
1123
                print('erro, registrador não existe')
1124
                sys.exit("erro, registrador não existe")
1125
            else:
1126
                bin_reg_d = '{0:05b}'.format(num_reg_d)
1127
                bin_reg_s = '{0:05b}'.format(num_reg_s)
1128
 
1129
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
1130
                self.mif_file.write(opcode_sprite_color + '')   # Opcode
1131
                self.mif_file.write(bin_reg_d + '')             # Destination register
1132
                self.mif_file.write(bin_reg_s + '')             # Source register
1133
                self.mif_file.write('0000000000000000' + ';')   # Blank space
1134
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
1135
        return
1136
 
1137
    def sprite_pos_instruct(self, line_index, line):
1138
        params = line.split(',')
1139
 
1140
        if (len(params) > 3):
1141
            print('erro, operandos demais')
1142
            sys.exit("erro, operandos demais")
1143
        else:
1144
            words = params[0].split()
1145
            params.remove(params[0])
1146
            words.extend(params)
1147
 
1148
            # words[0]: SPRITE_POS
1149
            # words[1]: REG_A
1150
            # words[2]: REG_B
1151
            # words[3]: REG_C
1152
 
1153
            #print(words)
1154
 
1155
            reg_a = words[1].strip()
1156
            reg_b = words[2].strip()
1157
            reg_c = words[3].strip()
1158
 
1159
            #print(reg_a)
1160
            #print(reg_b)
1161
            #print(reg_c)
1162
 
1163
            num_reg_a = register_dict.get(reg_a, -1)
1164
            num_reg_b = register_dict.get(reg_b, -1)
1165
            num_reg_c = register_dict.get(reg_c, -1)
1166
 
1167
            if (num_reg_a == -1 or num_reg_b == -1 or num_reg_c == -1):
1168
                print('erro, registrador não existe')
1169
                sys.exit("erro, registrador não existe")
1170
            else:
1171
                bin_reg_a = '{0:05b}'.format(num_reg_a)
1172
                bin_reg_b = '{0:05b}'.format(num_reg_b)
1173
                bin_reg_c = '{0:05b}'.format(num_reg_c)
1174
 
1175
                self.mif_file.write(str(line_index) + ' : ')    # Instruction memory address
1176
                self.mif_file.write(opcode_sprite_pos + '')     # Opcode
1177
                self.mif_file.write(bin_reg_a + '')             # Sprite level register
1178
                self.mif_file.write(bin_reg_b + '')             # Sprite row register
1179
                self.mif_file.write(bin_reg_c + '')             # Sprite column register
1180
                self.mif_file.write('00000000000' + ';')        # Blank space
1181
                self.mif_file.write('    -- ' + line + '\n')    # Original assembly instruction as a comment
1182
 
1183
        return
1184
 
1185
    def sprite_collision_bg_instruct(self, line_index, line):
1186
        return
1187
 
1188
    def sprite_collision_sp_instruct(self, line_index, line):
1189
        return
1190
 
1191
    def wait_vsync_instruct(self, line_index, line):
1192
        words = line.split()
1193
        if (len(words) > 1):
1194
            print('erro, operandos demais')
1195
            sys.exit("erro, operandos demais")
1196
        else:
1197
            self.mif_file.write(str(line_index) + ' : ')            # Instruction memory address
1198
            self.mif_file.write(opcode_wait_vsync + '')             # Opcode
1199
            self.mif_file.write('00000000000000000000000000' + ';') # Blank space
1200
            self.mif_file.write('    -- ' + line + '\n')            # Original assembly instruction as a comment
1201
        return
1202
 
1203
 
1204
if __name__ == '__main__':
1205
 
1206
    assemblerGUI = AssemblerGUI()
1207
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.