class GuiMainWindow(Frame): def __init__(self, master, environment): Frame.__init__(self, master) self.environment = environment self.number_of_devices = self.environment.number_of_devices self.cc2541_checked = IntVar() self.efm32_checked = IntVar() self.bluetooth_checked = IntVar() self.ni_usb_checked = IntVar() self.gpib_checked = IntVar() self.srfpc_return_code_list = [] self.eac_return_code_list = [] self.eb_id_list = [StringVar() for _ in range(self.number_of_devices)] self.jlink_sn_list = [StringVar() for _ in range(self.number_of_devices)] self.__loadEbIdFromEnvironment() self.__loadJlinkSnFromEnvironment() self.master = master self.__initUi() def __notImplementedYet(self): tkMessageBox.showinfo('Information', 'NOT IMPLEMENTED YET!!!') #=========================================================================== # Initialize and reset GUI #=========================================================================== def __initUi(self): self.grid() self.master.title('Shine Production') for i in range(3): self.rowconfigure(i, pad=5) self.columnconfigure(0, pad=5, weight=1) self.columnconfigure(1, pad=5, weight=1) self.columnconfigure(2, pad=5, weight=2) self.columnconfigure(3, pad=5, weight=1) # Status frame self.status_frame = LabelFrame(self, text='Status', relief=RIDGE) self.status_frame.grid = self.status_frame.grid(row=0, column=0, columnspan=FRAME_COLUMN_SPAN, padx=5, pady=5) for i in range(8): self.status_frame.rowconfigure(i, pad=3) for i in range(self.number_of_devices + 1): self.status_frame.columnconfigure(i, pad=3) Label(self.status_frame, text='EB ID').grid(row=0, column=0, sticky=W) Label(self.status_frame, text='J-Link Serial Number').grid(row=1, column=0, sticky=W) Label(self.status_frame, text='Status').grid(row=2, column=0, sticky=W) Label(self.status_frame, text='DUT').grid(row=3, column=0, sticky=W) self.eb_id_entry = [] self.jlink_sn_entry = [] self.dut_status_label = [] for i in range (self.number_of_devices): self.eb_id_entry.append(Entry(self.status_frame, textvariable=self.eb_id_list[i], justify=CENTER, width=10)) self.eb_id_entry[i].grid(row=0, column=i + 1) self.jlink_sn_entry.append(Entry(self.status_frame, textvariable=self.jlink_sn_list[i], justify=CENTER, width=10)) self.jlink_sn_entry[i].grid(row=1, column=i + 1) self.dut_status_label.append(Label(self.status_frame, text='status', bg=INITIATED_COLOR)) self.dut_status_label[i].grid(row=2, column=i + 1) Label(self.status_frame, text='#{}'.format(i + 1)).grid(row=3, column=i + 1) # Path frame self.path_frame = LabelFrame(self, text='Paths') self.path_frame.grid = self.path_frame.grid(row=1, column=0, columnspan=FRAME_COLUMN_SPAN, padx=5, pady=5) for i in range(5): self.path_frame.rowconfigure(i, pad=3) for i in range(3): self.path_frame.columnconfigure(i, pad=3) Label(self.path_frame, text='SmartRFProgConsole Path').grid(row=0, column=0, sticky=W) self.srfpc_path_label = Label(self.path_frame, text=shortenPath(self.environment.srfpc_path)) self.srfpc_path_label.grid(row=0, column=1, columnspan=FRAME_COLUMN_SPAN - 2, sticky=W) Button(self.path_frame, text=' ... ', command=self.setSrfpcPath).grid(row=0, column=FRAME_COLUMN_SPAN - 1, sticky=N + S + E + W) Label(self.path_frame, text='EACommander Path').grid(row=1, column=0, sticky=W) self.eac_path_label = Label(self.path_frame, text=shortenPath(self.environment.eac_path)) self.eac_path_label.grid(row=1, column=1, columnspan=FRAME_COLUMN_SPAN - 2, sticky=W) Button(self.path_frame, text=' ... ', command=self.setEacPath).grid(row=1, column=FRAME_COLUMN_SPAN - 1, sticky=N + S + E + W) Label(self.path_frame, text='CC2541 Firmware Path').grid(row=2, column=0, sticky=W) self.cc2541_firmware_path_label = Label(self.path_frame, text=shortenPath(self.environment.cc2541_firmware_path)) self.cc2541_firmware_path_label.grid(row=2, column=1, columnspan=FRAME_COLUMN_SPAN - 2, sticky=W) Button(self.path_frame, text=' ... ', command=self.setCc2541FirmwarePath).grid(row=2, column=FRAME_COLUMN_SPAN - 1, sticky=N + S + E + W) Label(self.path_frame, text='EFM32 Firmware Path').grid(row=3, column=0, sticky=W) self.efm32_firmware_path_label = Label(self.path_frame, text=shortenPath(self.environment.efm32_firmware_path)) self.efm32_firmware_path_label.grid(row=3, column=1, columnspan=FRAME_COLUMN_SPAN - 2, sticky=W) Button(self.path_frame, text=' ... ', command=self.setEfm32FirmwarePath).grid(row=3, column=FRAME_COLUMN_SPAN - 1, sticky=N + S + E + W) Label(self.path_frame, text='EFM32 Final Firmware Path').grid(row=4, column=0, sticky=W) self.efm32_final_firmware_path_label = Label(self.path_frame, text=shortenPath(self.environment.efm32_firmware_path_final)) self.efm32_final_firmware_path_label.grid(row=4, column=1, columnspan=FRAME_COLUMN_SPAN - 2, sticky=W) Button(self.path_frame, text=' ... ', command=self.setEfm32FinalFirmwarePath).grid(row=4, column=FRAME_COLUMN_SPAN - 1, sticky=N + S + E + W) # Initiate Verify, Start and Close buttons self.save_environment_button = Button(self, text='Save Environment', command=self.saveEnvironment) self.save_environment_button.grid(row=2, column=0, sticky=N+S+E+W) self.start_button = Button(self, text="Start", command=self.start2) self.start_button.grid(row=2, column=2, sticky=N+S+E+W) self.close_button = Button(self, text="Close", command=self.close) self.close_button.grid(row=2, column=3, sticky=N+S+E+W) def __resetStatusLabels(self): for i in range (self.number_of_devices): self.dut_status_label[i].config(text='status', bg=INITIATED_COLOR) #=========================================================================== # Load, save EB and J-Link devices IDs from to environment to display them # on the GUI #=========================================================================== def __loadEbIdFromEnvironment(self): for i in range(self.number_of_devices): self.eb_id_list[i].set(self.environment.eb_id_list[i]) def __loadJlinkSnFromEnvironment(self): for i in range(self.number_of_devices): self.jlink_sn_list[i].set(self.environment.jlink_sn_list[i]) def __saveEbIdToEnvironment(self): for i in range(self.number_of_devices): self.environment.eb_id_list[i] = self.eb_id_list[i].get() def __saveJlinkSnToEnvironment(self): for i in range(self.number_of_devices): self.environment.jlink_sn_list[i] = self.jlink_sn_list[i].get() #=========================================================================== # Update status labels on the GUI #=========================================================================== def __setStatusLabel(self, index, status): # self.srfpc_return_code_list[index] = status if status == SUCCESS_CODE: self.dut_status_label[index].config(text='Pass [{}]'.format(str(status)), bg=STATUS_OK_COLOR) elif status == IN_PROGRESS_CODE: self.dut_status_label[index].config(text='In Progress... [{}]'.format(str(status)), bg=STATUS_IN_PROGRESS_COLOR) elif status == -2: self.dut_status_label[index].config(text='FIX INTERNET', bg='blue') elif status == -3: self.dut_status_label[index].config(text='CANT CONNECT TO KEITHLEY', bg='blue') else: self.dut_status_label[index].config(text='Fail [{}]'.format(str(status)), bg=STATUS_ERROR_COLOR) self.update() def __drawStatusLabel(self, status_list): if type(status_list) != list or len(status_list) != self.number_of_devices: return for i in range(self.number_of_devices): self.__setStatusLabel(i, status_list[i]) #=========================================================================== # Update executable paths #=========================================================================== def setSrfpcPath(self): f = tkFileDialog.askopenfile(parent=self.master, mode='rb', title='Pick SmartRFProgConsole.exe file', filetype=(('EXE file', '*.exe'),)) if f: self.environment.srfpc_path = os.path.abspath(f.name) f.close() self.environment.save() self.srfpc_path_label.config(text=shortenPath(self.environment.srfpc_path)) self.srfpc_path_label.update() def setEacPath(self): f = tkFileDialog.askopenfile(parent=self.master, mode='rb', title='Pick eACommander.exe file', filetype=(('EXE file', '*.exe'),)) if f != None: self.environment.eac_path = os.path.abspath(f.name) f.close() self.environment.save() self.eac_path_label.config(text=shortenPath(self.environment.eac_path)) self.eac_path_label.update() def setCc2541FirmwarePath(self): f = tkFileDialog.askopenfile(parent=self.master, mode='rb', title='Pick CC2541 Firmware HEX file', filetype=(('HEX file', '*.hex'),)) if f != None: self.environment.cc2541_firmware_path = os.path.abspath(f.name) f.close() self.environment.save() self.cc2541_firmware_path_label.config(text=shortenPath(self.environment.cc2541_firmware_path)) self.cc2541_firmware_path_label.update() def setEfm32FirmwarePath(self): f = tkFileDialog.askopenfile(parent=self.master, mode='rb', title='Pick EFM32 Firmware BIN file', filetype=(('BIN file', '*.bin'),)) if f != None: self.environment.efm32_firmware_path = os.path.abspath(f.name) f.close() self.environment.save() self.efm32_firmware_path_label.config(text=shortenPath(self.environment.efm32_firmware_path)) self.efm32_firmware_path_label.update() def setEfm32FinalFirmwarePath(self): f = tkFileDialog.askopenfile(parent=self.master, mode='rb', title='Pick EFM32 Final Firmware BIN file', filetype=(('BIN file', '*.bin'),)) if f != None: self.environment.efm32_firmware_path_final = os.path.abspath(f.name) f.close() self.environment.save() self.efm32_final_firmware_path_label.config(text=shortenPath(self.environment.efm32_firmware_path_final)) self.efm32_final_firmware_path_label.update() def saveEnvironment(self): self.__saveEbIdToEnvironment() self.__saveJlinkSnToEnvironment() self.environment.save() tkMessageBox.showinfo('Information', 'Environment has been saved successfully!') def close(self): """ TODO: Save current parameters, state. """ if tkMessageBox.askokcancel('Confirmation', 'Are you sure you want to quit?'): self.quit() def __waitForContinueMessage(self): #P0.6 = ETM_TD0 test = -1 while test != 0: # THIS VALUE IS ALWAYS SOMETHING IS WRONG test = NI.captureDigitalInput('Dev1/port0/line6', 1)[0] def __sendContinueMessage(self): #P0.7 = ETM_TD1 NI.setDigitalOutput('Dev1/port0/line7', 128) NI.setDigitalOutput('Dev1/port0/line7', 0) def start2(self): self.__resetStatusLabels() self.start_button.config(state=DISABLED) self.start_button.update() self.__setStatusLabel(0, IN_PROGRESS_CODE) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~CC2541 and EFM32 FIRMWARE FLASH (PRODUCTION TEST FIRMWARE)~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dut_parameters = DutParameters(ATE_ID, self.environment.device_code_name, self.environment.device_type, self.environment.eb_id_list[0], self.environment.jlink_sn_list[0], self.environment) status = executeTestSequence(dut_parameters, log_queue) print 'Status: {}'.format(status) dut_parameters.logStatus(status) self.__setStatusLabel(0, status) self.start_button.config(state=ACTIVE) self.start_button.update()
class Editor(object): """ Finestra per l'editor di condice assembly """ def __init__(self, master, calcolatore): """ Inizializza i frame della finestra dell'Editor """ self.master = master self.CD = calcolatore # Codice Assembly self.codice = LabelFrame(self.master, text='Codice Assembly', relief=RIDGE, borderwidth=5, labelanchor='n', pady=5) self.codice.rowconfigure(0, weight=1) self.codice.columnconfigure(0, weight=1) self.codice.grid(row=1, column=0, rowspan=3, columnspan=5, sticky=W + E + N + S) self.menubar = Menu(self.master) self.create_widgets(self.menubar) def create_widgets(self, menubar): """ Crea il layout del programma, finestra dell'Editor """ # Menu self.filemenu = Menu(menubar, tearoff=0) self.filemenu.add_command(label='Apri', command=self.aprifile) self.filemenu.add_command(label='Salva', command=self.salvafile) self.filemenu.add_command(label='Cancella', command=self.cancella) self.filemenu.add_separator() self.filemenu.add_command(label='Esci', command=self.exit) menubar.add_cascade(label='Opzioni', menu=self.filemenu) self.master.config(menu=self.menubar) self.helpmenu = Menu(menubar, tearoff=0) self.helpmenu.add_command(label='Informazioni', command=self.infor) self.helpmenu.add_command(label='Legenda', command=self.leg) self.helpmenu.add_command(label='Guida', command=self.guida) menubar.add_cascade(label='Aiuto', menu=self.helpmenu) # Codice Assembly self.Inserisci = Text(self.codice, width=50, height=30, wrap=WORD) self.Inserisciscrollbar = Scrollbar(self.codice) self.Inserisciscrollbar.config(command=self.Inserisci.yview) self.Inserisci.config(yscrollcommand=self.Inserisciscrollbar.set) self.Inserisciscrollbar.grid(row=0, column=1, sticky=N + S) self.Inserisci.grid(row=0, column=0, sticky=W) def exit(self): """ Esce dal programma """ if askquestion('Exit', 'Sicuro di voler uscire?') == YES: self.master.quit() self.master.destroy() else: showinfo('Suggerimento', """Forse e' meglio fare una pausa!""", icon=WARNING) def aprifile(self): """ Apre un file assembly e lo mostra a video per essere modificato """ path = askopenfilename(title='Apri codice assembly', filetypes=[('Assembly', '.asm'), ('Testo', '.txt'), ('All', '*')]) if path != '': file = open(path, 'r') temp = file.read() self.Inserisci.delete(1.0, END) self.Inserisci.insert(INSERT, temp.decode('ascii', 'ignore')) file.close() def cancella(self): """ Cancella l'attuale file assembly caricato """ if askquestion('Cancella', 'Si vuole cancellare tutto il codice assembly?') == YES: self.Inserisci.delete(1.0, END) def salvafile(self): """ Salva il file assembly su cui si sta lavorando """ contenuto = self.Inserisci.get(1.0, END) contenuto = contenuto.encode('ascii', 'ignore') path = asksaveasfilename(title='Salva codice assembly', defaultextension=[('Assembly', '.asm'), ('Testo', '.txt'), ('All', '*')], filetypes=[('Assembly', '.asm'), ('Testo', '.txt'), ('All', '*')]) print path if path != '': file = open(path, 'w') file.write(str(contenuto)) file.close() @staticmethod def infor(): """ Visualizza le informazioni riguardante il programma """ nome = """pdp8 emulator""" stringa = """ Pdp8 Emulator °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° Version = 1.6.2 Tested with = python 2.6 & 2.7 ------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Mirco Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------- Contact: [email protected] Collaborators : Walter Valentini """ showinfo(nome, stringa) @staticmethod def leg(): """ Visualizza le informazioni riguardanti colori """ nome = """pdp8 Legenda""" stringa = """ Rosso = indirizzo puntato da PC Giallo = indirizzo puntato da MAR Verde = ultima istruzione eseguita """ showinfo(nome, stringa) @staticmethod def guida(): """ Piccola guida """ nome = """pdp8 Guida""" stringa = """ LOAD = Carica il assembly nella memoria del Calcolatore Didattico (CD). STEP = Avanza del numero di step indicato (di default 1). Uno step equivale all'esecuzione di una singola istruzione. mini STEP = Esegue un singolo ciclo in base alle variabili F ed R dell'unità di controllo. micro STEP = Esegue ogni singola microistruzione. Set n STEP = Setta il numero di step. Set Delay = Setta il tempo di aggiornamento del CD. START = Avvia il CD, ma non l'esecuzione del codice. Per eseguire il codice, utilizzare step o esegui una volta avviata la macchina. RESET = Resetta il CD allo stato iniziale. STOP = Ferma il CD e quindi anche l'esecuzione del codice. BREAK = Aggiunge o toglie un break alla cella indicata in esadecimale. CONTINUA = Continua l'esecuzione del programma dopo un break. Equivale a premere in sequenza START ed ESEGUI. ESEGUI = Esegue il codice fino all'istruzione HLT, che arresta la macchina. """ showinfo(nome, stringa)
class Editor(object): """ Finestra per l'editor di condice assembly """ def __init__(self, master, calcolatore): """ Inizializza i frame della finestra dell'Editor """ self.master = master self.CD = calcolatore # Codice Assembly self.codice = LabelFrame( self.master, text='Codice Assembly', relief=RIDGE, borderwidth=5, labelanchor='n', pady=5) self.codice.rowconfigure(0, weight=1) self.codice.columnconfigure(0, weight=1) self.codice.grid( row=1, column=0, rowspan=3, columnspan=5, sticky=W + E + N + S) self.menubar = Menu(self.master) self.create_widgets(self.menubar) def create_widgets(self, menubar): """ Crea il layout del programma, finestra dell'Editor """ # Menu self.filemenu = Menu(menubar, tearoff=0) self.filemenu.add_command(label='Apri', command=self.aprifile) self.filemenu.add_command(label='Salva', command=self.salvafile) self.filemenu.add_command(label='Cancella', command=self.cancella) self.filemenu.add_separator() self.filemenu.add_command(label='Esci', command=self.exit) menubar.add_cascade(label='Opzioni', menu=self.filemenu) self.master.config(menu=self.menubar) self.helpmenu = Menu(menubar, tearoff=0) self.helpmenu.add_command(label='Informazioni', command=self.infor) self.helpmenu.add_command(label='Legenda', command=self.leg) self.helpmenu.add_command(label='Guida', command=self.guida) menubar.add_cascade(label='Aiuto', menu=self.helpmenu) # Codice Assembly self.Inserisci = Text(self.codice, width=50, height=30, wrap=WORD) self.Inserisciscrollbar = Scrollbar(self.codice) self.Inserisciscrollbar.config(command=self.Inserisci.yview) self.Inserisci.config(yscrollcommand=self.Inserisciscrollbar.set) self.Inserisciscrollbar.grid(row=0, column=1, sticky=N + S) self.Inserisci.grid(row=0, column=0, sticky=W) def exit(self): """ Esce dal programma """ if askquestion('Exit', 'Sicuro di voler uscire?') == YES: self.master.quit() self.master.destroy() else: showinfo( 'Suggerimento', """Forse e' meglio fare una pausa!""", icon=WARNING) def aprifile(self): """ Apre un file assembly e lo mostra a video per essere modificato """ path = askopenfilename(title='Apri codice assembly', filetypes=[('Assembly', '.asm'), ('Testo', '.txt'), ('All', '*')]) if path != '': file = open(path, 'r') temp = file.read() self.Inserisci.delete(1.0, END) self.Inserisci.insert(INSERT, temp.decode('ascii', 'ignore')) file.close() def cancella(self): """ Cancella l'attuale file assembly caricato """ if askquestion('Cancella', 'Si vuole cancellare tutto il codice assembly?') == YES: self.Inserisci.delete(1.0, END) def salvafile(self): """ Salva il file assembly su cui si sta lavorando """ contenuto = self.Inserisci.get(1.0, END) contenuto = contenuto.encode('ascii', 'ignore') path = asksaveasfilename(title='Salva codice assembly', defaultextension=[ ('Assembly', '.asm'), ('Testo', '.txt'), ('All', '*')], filetypes=[('Assembly', '.asm'), ('Testo', '.txt'), ('All', '*')]) print path if path != '': file = open(path, 'w') file.write(str(contenuto)) file.close() @staticmethod def infor(): """ Visualizza le informazioni riguardante il programma """ nome = """pdp8 emulator""" stringa = """ Pdp8 Emulator °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° Version = 1.6.2 Tested with = python 2.6 & 2.7 ------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Mirco Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------- Contact: [email protected] Collaborators : Walter Valentini """ showinfo(nome, stringa) @staticmethod def leg(): """ Visualizza le informazioni riguardanti colori """ nome = """pdp8 Legenda""" stringa = """ Rosso = indirizzo puntato da PC Giallo = indirizzo puntato da MAR Verde = ultima istruzione eseguita """ showinfo(nome, stringa) @staticmethod def guida(): """ Piccola guida """ nome = """pdp8 Guida""" stringa = """ LOAD = Carica il assembly nella memoria del Calcolatore Didattico (CD). STEP = Avanza del numero di step indicato (di default 1). Uno step equivale all'esecuzione di una singola istruzione. mini STEP = Esegue un singolo ciclo in base alle variabili F ed R dell'unità di controllo. micro STEP = Esegue ogni singola microistruzione. Set n STEP = Setta il numero di step. Set Delay = Setta il tempo di aggiornamento del CD. START = Avvia il CD, ma non l'esecuzione del codice. Per eseguire il codice, utilizzare step o esegui una volta avviata la macchina. RESET = Resetta il CD allo stato iniziale. STOP = Ferma il CD e quindi anche l'esecuzione del codice. BREAK = Aggiunge o toglie un break alla cella indicata in esadecimale. CONTINUA = Continua l'esecuzione del programma dopo un break. Equivale a premere in sequenza START ed ESEGUI. ESEGUI = Esegue il codice fino all'istruzione HLT, che arresta la macchina. """ showinfo(nome, stringa)
class Emulatore(object): """ Interfaccia grafica per l'emulatore del pdp8 """ def __init__(self, master, codice, calcolatore, emulatore): """ Inizializza i frame per l'interfaccia dell'emulatore """ self.CD = calcolatore self.codice = codice self.delay = 100 self.master = Frame(master) self.root = emulatore # Memoria Ram self.ram = LabelFrame( self.master, text='Memoria RAM', relief=RIDGE, borderwidth=5, labelanchor='n', pady=5) self.ram.rowconfigure(0, weight=1) self.ram.columnconfigure(0, weight=1) self.ram.grid( row=0, column=0, rowspan=3, columnspan=5, sticky=W + E + N + S) # Controlli self.controlli = Frame(self.master, padx=10, pady=10) self.controlli.grid(row=0, column=5, rowspan=1) # Status CD self.registri = LabelFrame( self.master, text='REGISTRI', relief=RIDGE, borderwidth=5, labelanchor='n', padx=25, pady=10) self.registri.grid(row=0, column=6, rowspan=1, sticky=W + E + N + S) self.unita = LabelFrame( self.master, text='UC', relief=RIDGE, borderwidth=5, labelanchor='n', padx=10, pady=10) self.unita.grid(row=2, column=6, rowspan=1, sticky=N) # Var self.variabili = Frame(self.master) self.variabili.grid(row=2, column=5) self.nstep = LabelFrame( self.variabili, text='Num. Step', relief=RIDGE, borderwidth=5, labelanchor='n') self.nstep.grid(row=0, column=5, sticky=W + E) self.delays = LabelFrame( self.variabili, text='Delay', relief=RIDGE, borderwidth=5, labelanchor='n') self.delays.grid(row=1, column=5, sticky=W + E) self.tempo = LabelFrame( self.variabili, text='Tempo', relief=RIDGE, borderwidth=5, labelanchor='n') self.tempo.grid(row=1, column=6, sticky=W + E) # Unita' di controllo self.unitas = LabelFrame( self.unita, text='S', labelanchor='s', padx=10) self.unitas.grid(row=0, column=0, sticky=N) self.unitaf = LabelFrame( self.unita, text='F', labelanchor='s', padx=10) self.unitaf.grid(row=0, column=1, sticky=N) self.unitar = LabelFrame( self.unita, text='R', labelanchor='s', padx=10) self.unitar.grid(row=0, column=2, sticky=N) self.unitaint = LabelFrame( self.unita, text='Int.', labelanchor='s', padx=10) self.unitaint.grid(row=0, column=3, sticky=N) # Registri self.programc = LabelFrame( self.registri, text='PC', relief=FLAT, labelanchor='e', padx=5) self.programc.grid(row=0, column=0, sticky=W + E) self.mar = LabelFrame( self.registri, text='MAR', relief=FLAT, labelanchor='e', padx=5) self.mar.grid(row=1, column=0, sticky=W + E) self.mbr = LabelFrame( self.registri, text='MBR', relief=FLAT, labelanchor='e', padx=5) self.mbr.grid(row=2, column=0, sticky=W + E) self.lopr = LabelFrame( self.registri, text='OPR', relief=FLAT, labelanchor='e', padx=5) self.lopr.grid(row=3, column=0, sticky=W + E) self.vari = LabelFrame( self.registri, text='I', relief=FLAT, labelanchor='e', padx=5) self.vari.grid(row=4, column=0, sticky=W + E) self.vare = LabelFrame( self.registri, text='E', relief=FLAT, labelanchor='e', padx=5) self.vare.grid(row=5, column=0, sticky=W + E) self.lac = LabelFrame( self.registri, text='AC', relief=FLAT, labelanchor='e', padx=5) self.lac.grid(row=6, column=0, sticky=W + E) self.lacint = LabelFrame( self.registri, text='INT AC', relief=FLAT, labelanchor='e', padx=5) self.lacint.grid(row=7, column=0, sticky=W + E) self.lachex = LabelFrame( self.registri, text='HEX AC', relief=FLAT, labelanchor='e', padx=5) self.lachex.grid(row=8, column=0, sticky=W + E) # Microistruzioni self.micro = LabelFrame( self.master, text='Microistruzioni eseguite', relief=RIDGE, borderwidth=5, labelanchor='n', pady=5) self.micro.rowconfigure(0, weight=1) self.micro.columnconfigure(0, weight=1) self.micro.grid( row=3, column=4, rowspan=5, columnspan=5, sticky=W + E + N + S) # Inout self.inout = LabelFrame( self.master, text='Input & Output', relief=RIDGE, borderwidth=5, labelanchor='n', pady=5) self.inout.rowconfigure(0, weight=1) self.inout.columnconfigure(0, weight=1) self.inout.grid(row=3, column=0, columnspan=4, sticky=W + E + N + S) self.create_widgets() def create_widgets(self): """ Crea il layout del programma, finestra dell'emulatore """ # Memoria RAM self.Visualizza = Text(self.ram, width=80) self.Visualizzascrollbar = Scrollbar(self.ram) self.Visualizzascrollbar.config(command=self.Visualizza.yview) self.Visualizza.config(yscrollcommand=self.Visualizzascrollbar.set) self.Visualizzascrollbar.grid(row=0, column=1, sticky=N + S) self.Visualizza.grid(row=0, column=0, sticky=W) # INOUT self.Visualizzainout = Text( self.inout, width=62, height=7, fg='green', bg='black') self.Visualizzascrollbar_inout = Scrollbar(self.inout) self.Visualizzascrollbar_inout.config( command=self.Visualizzainout.yview) self.Visualizzainout.config( yscrollcommand=self.Visualizzascrollbar_inout.set) self.Visualizzascrollbar_inout.grid(row=0, column=1, sticky=N + S) self.Visualizzainout.grid(row=0, column=0, sticky=W) # Mircroistruzioni self.Visualizzamicro = Text(self.micro, width=55, height=7) self.Visualizzascrollbar_m = Scrollbar(self.micro) self.Visualizzascrollbar_m.config(command=self.Visualizzamicro.yview) self.Visualizzamicro.config( yscrollcommand=self.Visualizzascrollbar_m.set) self.Visualizzascrollbar_m.grid(row=0, column=1, sticky=N + S) self.Visualizzamicro.grid(row=0, column=0, sticky=W) # Pulsanti self.butload = Button( self.controlli, text='LOAD', anchor=CENTER, width=15, command=self.loading, bg='SkyBlue') self.butload.grid(row=0, column=0) self.butstep = Button( self.controlli, text='Step', anchor=CENTER, width=15, command=self.step, bg='linen') self.butstep.grid(row=1, column=0) self.butminstep = Button( self.controlli, text='miniStep', anchor=CENTER, width=15, command=self.mini_step, bg='linen') self.butminstep.grid(row=2, column=0) self.butstep = Button(self.controlli, text='microStep', anchor=CENTER, width=15, command=self.micro_step, bg='linen') self.butstep.grid(row=3, column=0) self.butsetstep = Button( self.controlli, text='Set n Step', anchor=CENTER, width=15, command=self.setnstep, bg='linen') self.butsetstep.grid(row=4, column=0) self.butsetdelay = Button( self.controlli, text='Set Delay', anchor=CENTER, width=15, command=self.setdelay, bg='linen') self.butsetdelay.grid(row=5, column=0) self.butstart = Button( self.controlli, text='START', anchor=CENTER, width=15, command=self.start, bg='DarkOliveGreen3') self.butstart.grid(row=6, column=0) self.butreset = Button( self.controlli, text='RESET', anchor=CENTER, width=15, command=self.resetCD, bg='Orange3') self.butreset.grid(row=7, column=0) self.butstop = Button( self.controlli, text='STOP', anchor=CENTER, width=15, command=self.stop, bg='IndianRed') self.butstop.grid(row=8, column=0) self.butbreak = Button( self.controlli, text='BREAK', anchor=CENTER, width=15, command=self.breakpoint, bg='Magenta2') self.butbreak.grid(row=9, column=0) self.butcontinue = Button( self.controlli, text='CONTINUA', anchor=CENTER, width=15, command=self.continua, bg='Magenta2') self.butcontinue.grid(row=10, column=0) self.butesegui = Button( self.controlli, text='ESEGUI', anchor=CENTER, width=15, command=self.esegui, bg='Yellow') self.butesegui.grid(row=11, column=0) # Labels self.labelprogramc = Label( self.programc, text='00000000000', relief=SUNKEN, bg='red') self.labelprogramc.grid() self.labelmar = Label( self.mar, text='00000000000', relief=SUNKEN, bg='yellow') self.labelmar.grid() self.labelmbr = Label(self.mbr, text='000000000000000', relief=SUNKEN) self.labelmbr.grid() self.labelvari = Label(self.vari, text='0', relief=SUNKEN) self.labelvari.grid() self.labelopr = Label(self.lopr, text='000', relief=SUNKEN) self.labelopr.grid() self.labelucs = Label(self.unitas, text='0') self.labelucs.grid() self.labelucf = Label(self.unitaf, text='0') self.labelucf.grid() self.labelucr = Label(self.unitar, text='0') self.labelucr.grid() self.labelucint = Label(self.unitaint, text='0') self.labelucint.grid() self.labelnstep = Label(self.nstep, text='1') self.labelnstep.grid() self.labeldelay = Label(self.delays, text=str(self.delay)) self.labeldelay.grid() self.labeltempo = Label(self.tempo, text=str(self.CD.tempo)) self.labeltempo.grid() self.labelac = Label(self.lac, text='000000000000000', relief=SUNKEN) self.labelac.grid() self.labelacint = Label( self.lacint, text='000000000000000', relief=SUNKEN) self.labelacint.grid() self.labelachex = Label( self.lachex, text='000000000000000', relief=SUNKEN) self.labelachex.grid() self.labelvare = Label(self.vare, text='0', relief=SUNKEN) self.labelvare.grid() def continua(self): """ Continua l'esecuzione dopo un break """ self.CD.S = True self.esegui() def micro_step(self): """ Esegue il metodo step del calcolatore didattico ed aggiorna """ if self.CD.S: self.CD.step(self.root, self.codice) if self.CD.tempo == 0 and not self.CD.F and not self.CD.R: self.CD.previstr = self.CD.nextistr self.aggiornaall() def step(self): """ Esegue il metodo step del calcolatore didattico ed aggiorna """ var = True if self.CD.S and self.CD.nstep > 0: while var and self.CD.S: self.CD.step(self.root, self.codice) if not self.CD.F and not self.CD.R and self.CD.tempo == 0: self.CD.nstep -= 1 self.aggiornaall() self.CD.previstr = self.CD.nextistr var = False if self.CD.nstep > 0: self.butstep.after(self.delay, self.step) else: self.CD.setnstep(1) else: self.CD.setnstep(1) self.aggiornaall() def esegui(self): """ Esegue il programma fino all'arresto della macchina tramite l'istruzione HLT """ while self.CD.S: self.CD.step(self.root, self.codice) if not self.CD.F and not self.CD.R and self.CD.tempo == 0: self.aggiornaall() self.CD.previstr = self.CD.nextistr break if self.CD.S: self.butesegui.after(self.delay, self.esegui) else: self.CD.setnstep(1) self.aggiornaall() def mini_step(self): """ Esegue un singolo ciclo della macchina """ if self.CD.S: for x in range(0, 4): self.CD.step(self.root, self.codice) self.CD.nstep = 1 self.aggiornaall() if self.CD.F is False and self.CD.R is False: self.CD.previstr = self.CD.nextistr def cerca_istr_prev(self): """ Evidenzia di VERDE l'ultima istruzione eseguita """ if self.CD.PC == '000000000000': return try: if self.CD.previstr == '' and int(self.CD.PC, 2) == self.CD.START: return else: pospc = str(3.0 + self.CD.previstr) self.Visualizza.tag_add( "PISTR", str(pospc[:-1] + '16'), str(pospc[:-1] + 'end')) self.Visualizza.tag_config("PISTR", background="green") self.Visualizza.see(pospc) except TypeError: pass # Errore che si ottiene durante il reset del CD # NOTA : METODO NON NECESSARIO NEL PROGRAMMA FINALE # def cerca_istr_corr(self): # """ # Evidenzia di verde l'istruzione che si dovrà eseguire # """ # if self.CD.PC == '000000000000': # return # try: # if int(self.CD.PC,2) == self.CD.START: # Inizio esecuzione del programma # Il PC e l'istruzione da eseguire sono allo stesso 'livello' # pos = str(3.0) # self.Visualizza.tag_add("ISTR", str(pos[0]+'.16'), str(pos[:-1]+'end')) # self.Visualizza.tag_config("ISTR", background = "green") # else: # pospc = str(3.0 + self.CD.nextistr) # self.Visualizza.tag_add("ISTR", str(pospc[:-1]+'16'), str(pospc[:-1]+'end')) # self.Visualizza.tag_config("ISTR", background = "green") # self.Visualizza.see(pospc) # except TypeError: # pass ## Errore che si ottiene durante il reset del CD def cerca_MAR(self): """ Evidenzia di giallo l'indirizzo puntato dal MAR """ try: pos = 3.0 stringa = self.Visualizza.get(str(pos), 'end') while stringa[:12] != self.CD.MAR and int(pos) < len(self.CD.RAM) + 3 and len(self.CD.RAM) > 0: pos += 1 stringa = self.Visualizza.get(str(pos), 'end') if int(pos) >= len(self.CD.RAM) + 3: return self.Visualizza.tag_add("MAR", pos, str(float(pos) + 0.12)) self.Visualizza.tag_config("MAR", background="yellow") except TypeError: pass # Errore che si ottiene durante il reset del CD def cerca_PC(self): """ Evidenzia di rosso l'indirizzo puntato da PC """ try: pos = 3.0 stringa = self.Visualizza.get(str(pos), 'end') while stringa[:12] != self.CD.PC and int(pos) < len(self.CD.RAM) + 3 and len(self.CD.RAM) > 0: pos += 1 stringa = self.Visualizza.get(str(pos), 'end') if int(pos) >= len(self.CD.RAM) + 3: return self.Visualizza.tag_add("PC", pos, str(float(pos) + 0.12)) self.Visualizza.tag_config("PC", background="red") except TypeError: pass # Errore che si ottiene durante il reset del CD def aggiornaout(self): """ Aggiorna micro e input/output """ self.aggiornamicro() self.aggiornainout() def aggiornamicro(self): """ Aggiorna le microistruzioni eseguite """ self.Visualizzamicro.delete(1.0, END) stringa = self.CD.microistruzioni self.Visualizzamicro.insert(INSERT, stringa) self.Visualizzamicro.see(END) def aggiornainout(self): """ Aggiorna gli input ed output di sistema """ self.Visualizzainout.delete(1.0, END) stringa = self.CD.inout self.Visualizzainout.insert(INSERT, stringa) self.Visualizzainout.see(END) def aggiornaram(self): """ Aggiorna lo stato della RAM """ self.Visualizza.delete(1.0, END) stringa = self.CD.statusRAM() self.Visualizza.insert(INSERT, stringa) self.cerca_MAR() self.cerca_PC() self.cerca_istr_prev() # self.cerca_istr_corr() #Non più necessaria nella versione finale def aggiornareg(self): """ Aggiorna lo stato dei Registri """ self.labelprogramc.config(text=self.CD.PC) self.labelmar.config(text=self.CD.MAR) self.labelmbr.config(text=self.CD.MBR) self.labelac.config(text=self.CD.AC) self.labelacint.config(text=str(self.CD.range(int(self.CD.AC, 2)))) self.labelachex.config( text=str((hex(int(self.CD.AC, 2))[2:].upper())).zfill(4)) self.labelvare.config(text=self.CD.E) self.labelvari.config(text=self.CD.I) self.labelopr.config(text=self.CD.OPR) def aggiornauc(self): """ Aggiorna lo stato dell'unita' di controllo """ if self.CD.S and not self.CD.breaks: self.labelucs.config(text=self.CD.S, bg='green') self.unitas.config(bg='green') elif not self.CD.S and self.CD.breaks: self.labelucs.config(text=self.CD.S, bg='Magenta2') self.unitas.config(bg='Magenta2') else: self.labelucs.config(text=self.CD.S, bg='red') self.unitas.config(bg='red') self.labelucf.config(text=self.CD.F) self.labelucr.config(text=self.CD.R) self.labelucint.config(text=self.CD.Interrupt) self.labeltempo.config(text=self.CD.tempo) def aggiornaall(self): """ Aggiorna tutto """ self.aggiornaram() self.aggiornareg() self.aggiornauc() self.aggiornamicro() self.aggiornaout() self.labelnstep.config(text=self.CD.nstep) def loading(self): """ Carica il contenuto del codice assembly decodificandolo in binario nella RAM """ contenuto = self.codice.Inserisci.get(1.0, END) if len(contenuto) > 1: self.resetCD() if self.CD.carica(contenuto.decode('ascii', 'ignore'), self) is not None: self.CD.S = 0 self.aggiornaall() def resetCD(self): """ Resetta il calcolatore didattico """ self.CD = pdp8() self.aggiornaall() def start(self): """ Mette la variabile Start (S) ad 1, cioe' True """ self.CD.S = True if self.CD.breaks == True: self.CD.breaks = False self.aggiornauc() def stop(self): """ Mette la variabile Start (S) ad 0, cioe' False """ self.CD.S = False self.aggiornauc() def setnstep(self): """ Setta, in base al valore passato, il numero di cicli da eseguire """ temp = askinteger("Num Step", "Numero di step da eseguire", initialvalue=1, minvalue=1, parent=self.root) if temp is None: self.CD.setnstep(1) else: self.CD.setnstep(temp) self.labelnstep.config(text=self.CD.nstep) def setdelay(self): """ Setta, in base al valore passato, il ritardo di esecuzione. Il valore è espresso in millisecondi, di default = 1000 """ temp = askinteger("Set Delay", "Ritardo in millisecondi", initialvalue=100, minvalue=1, parent=self.root) if temp is not None: self.delay = temp self.labeldelay.config(text=self.delay) def breakpoint(self): """ Setta o elimina i breakpoint dal programma caricato in memoria """ temp = askstring( "Cella di memoria", "Indirizzo esadecimale", parent=self.root) if temp is not None: temp = self.CD.binario(int(temp, 16)).zfill(12) self.CD.breakpoint(temp) self.aggiornaram() def exit(self): """ Esce dal programma """ if askquestion('Exit', 'Sicuro di voler uscire?', parent=self.master) == YES: self.codice.master.quit() self.codice.master.destroy() else: showinfo('Suggerimento', """Forse e' meglio fare una pausa!""", icon=WARNING, parent=self.master)