USB Device Programming class project. This project allows a Python/Tk program running on a PC host to monitor/control a test-CPU programmed into an altera development board.

Dependencies:   C12832_lcd USBDevice mbed-rtos mbed mmSPI

Revision:
4:92539904a4ad
Child:
8:db29cce17a33
diff -r 659ffc90b59e -r 92539904a4ad mmPython/mmUI.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmPython/mmUI.txt	Sun Sep 01 02:58:57 2013 +0000
@@ -0,0 +1,740 @@
+#!/usr/bin/python -tt                       # tt: detect mixed space/tab.
+#---copyright-----------------------------------#-------------------------------
+#   licensed for personal and academic use.
+#   commercial use must be approved by the account-holder of
+#   gated.clock@gmail.com
+#-------imports---------------------------------#-------------------------------
+from   Tkinter     import *         # Tk graphics.
+import mmUSBserial              # USB Serial object.
+from   mmUSBserial import *
+import time                 # Time object.
+from   time import time, sleep
+import threading                # Threading object.
+import tkFileDialog             # File-select dialog object.'
+import os                   # import os  library.
+#=======class===================================#===============================
+#-----------------------------------------------#-------------------------------
+'''
+    licensed for personal and accedemic use.
+    commercial use must be approved by the account-holder of
+    gated.clock@gmail.com
+'''     
+#-----------------------------------------------#-------------------------------
+'''
+    description: 
+
+    python/Tk code for interfacing with the mbed.org system.
+    this code provides a UI which is used to communicate over USB
+    to the mbed.org processor, and in turn the toy CPU programmed
+    into the altera device.
+
+    this code provides a UI which is used to monitor and write-to the
+    toy CPU's registers and its main memory. 
+
+    I/O capability:
+
+    * R0 write/read.
+    * R1 write/read.
+    * R2 write/read.
+    * R3 write/read.
+    * PC write/read.  (that's 'Program Counter'.)
+    * IR write/read.  (that's 'Instruction Register'.)
+    * MM address.     (that's 'Main Memory.')
+    * MM content.
+
+    Button Controls:
+
+    * USB Connect/Disconnect.
+    * Register Read.
+    * Register Write.
+    * Main Memory Read.
+    * Main Memory Write.
+    * Main Memory Load-From-File.
+    * Main Memory Dump-To-File.
+    * Step CPU.
+    * Run-Fast, Run-Slow, Stop CPU.
+    * Run Test.
+    * Exit.
+
+'''
+#-----------------------------------------------#-------------------------------
+if (1):                     # allow further indentation.                
+    class mmUI:                 # UI class.
+#-----------------------------------------------#-------------------------------
+      def __init__(self,masterWidget):      # constructor.
+
+        self.__masterWidget = masterWidget  # promote to object scope.
+
+                        # master widget title.
+        self.__masterWidget.wm_title("CPU Control")
+
+        self.__frame = Frame(masterWidget)  # create frame widget.
+        self.__frame.grid(column=0, row=0)  # use grid packer.
+
+        self.__connected   = 0      # not yet __connected to USB.
+        self.__isRunning   = 0      # program execution not running.
+        self.__testRunning = 0      # test mode not runing.
+        self.__testIter    = 0      # test mode iteration count.
+        self.__sleepVal    = 0.04       # serial transceive sleep.
+
+        
+        self.uiR0      (0, 1, 10)       # label/entry widgets (x, y, width)
+        self.uiR1      (0, 2, 10)
+        self.uiR2      (0, 3, 10)
+        self.uiR3      (0, 4, 10)
+        self.uiPC      (0, 5, 10)
+        self.uiIR      (0, 6, 10)
+        self.uimmADR   (0, 7, 10)
+        self.uimmVAL   (0, 8, 10)
+
+        self.uiConnect (3,  1, 8)       # button widgets (x, y, width)
+        self.uiRegRead (3,  2, 8)
+        self.uiRegWrite(3,  3, 8)
+        self.uimmRead  (3,  4, 8)
+        self.uimmWrite (3,  5, 8)
+        self.uiProg    (3,  6, 8)
+        self.uimmDump  (3,  7, 8)
+        self.uiStep    (3,  8, 8)
+        self.uiRun     (3,  9, 8)
+        self.uiTest    (3, 10, 8)
+        self.uiExit    (3, 11, 8)
+
+        self.refreshUI()            # initial content display.
+
+#-----------------------------------------------#-------------------------------    
+      def __del__(self):                    # destructor.
+        print "object destroyed."
+#-----------------------------------------------#-------------------------------
+#     WIDGETS: BEGIN LABEL/ENTRY PAIRS. #===============================
+#-----------------------------------------------#-------------------------------
+      def uiR0(self,dColumn,dRow,dWidth):   # R0.
+
+        dColumnPlusOne = dColumn + 1
+
+        self.__R0Label = Label(self.__frame, text="R0")
+        self.__R0Label.grid(column=dColumn, row=dRow, sticky=(E))
+    
+        self.__R0Entry = Entry(self.__frame, width=dWidth, background="GREEN")
+        self.__R0Entry.grid(column=dColumnPlusOne, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+      def uiR1(self,dColumn,dRow,dWidth):   # R1.
+
+        dColumnPlusOne = dColumn + 1
+
+        self.__R1Label = Label(self.__frame, text="R1")
+        self.__R1Label.grid(column=dColumn, row=dRow, sticky=(E))
+    
+        self.__R1Entry = Entry(self.__frame, width=dWidth, background="GREEN")
+        self.__R1Entry.grid(column=dColumnPlusOne, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+      def uiR2(self,dColumn,dRow,dWidth):   # R2.
+
+        dColumnPlusOne = dColumn + 1
+
+        self.__R2Label = Label(self.__frame, text="R2")
+        self.__R2Label.grid(column=dColumn, row=dRow, sticky=(E))
+    
+        self.__R2Entry = Entry(self.__frame, width=dWidth, background="GREEN")
+        self.__R2Entry.grid(column=dColumnPlusOne, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+      def uiR3(self,dColumn,dRow,dWidth):   # R3.
+
+        dColumnPlusOne = dColumn + 1
+
+        self.__R3Label = Label(self.__frame, text="R3")
+        self.__R3Label.grid(column=dColumn, row=dRow, sticky=(E))
+    
+        self.__R3Entry = Entry(self.__frame, width=dWidth, background="GREEN")
+        self.__R3Entry.grid(column=dColumnPlusOne, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+      def uiPC(self,dColumn,dRow,dWidth):   # program counter.
+
+        dColumnPlusOne = dColumn + 1
+
+        self.__PCLabel = Label(self.__frame, text="PC")
+        self.__PCLabel.grid(column=dColumn, row=dRow, sticky=(E))
+    
+        self.__PCEntry = Entry(self.__frame, width=dWidth, background="ORANGE")
+        self.__PCEntry.grid(column=dColumnPlusOne, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+      def uiIR(self,dColumn,dRow,dWidth):   # instruction register.
+
+        dColumnPlusOne = dColumn + 1
+
+        self.__IRLabel = Label(self.__frame, text="IR")
+        self.__IRLabel.grid(column=dColumn, row=dRow, sticky=(E))
+    
+        self.__IREntry = Entry(self.__frame, width=dWidth, background="ORANGE")
+        self.__IREntry.grid(column=dColumnPlusOne, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+      def uimmADR(self,dColumn,dRow,dWidth):# mmADR.
+
+        dColumnPlusOne = dColumn + 1
+
+        self.__mmADRLabel = Label(self.__frame, text="mmADR")
+        self.__mmADRLabel.grid(column=dColumn, row=dRow, sticky=(E))
+    
+        self.__mmADREntry = Entry(self.__frame, width=dWidth, 
+                                      background="MAROON", foreground="WHITE")
+        self.__mmADREntry.grid(column=dColumnPlusOne, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------    
+      def uimmVAL(self,dColumn,dRow,dWidth):# mmVAL.    
+
+        dColumnPlusOne = dColumn + 1
+
+        self.__mmVALLabel = Label(self.__frame, text="mmVAL")
+        self.__mmVALLabel.grid(column=dColumn, row=dRow, sticky=(E))
+    
+        self.__mmVALEntry = Entry(self.__frame, width=dWidth, 
+                                      background="MAROON", foreground="WHITE")
+        self.__mmVALEntry.grid(column=dColumnPlusOne, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+#     WIDGETS: BEGIN BUTTONS.       #===============================
+#-----------------------------------------------#-------------------------------
+                        # generate the 'connect' button.
+      def uiConnect(self,dColumn,dRow,dWidth):  
+
+        self.__connectButton = Button(self.__frame, text="CONNECT", 
+                                          command=self.selectConnectButtonPressed,
+                                          background="RED",
+                                          width = dWidth)
+
+        self.__connectButton.grid(column=dColumn, row=dRow, sticky=(E))
+#-----------------------------------------------#-------------------------------
+                        # generate the register-read button.
+      def uiRegRead(self,dColumn,dRow,dWidth):
+        self.__RegReadButton = Button(self.__frame, text="REG READ", 
+                                        command=self.selectRegReadButtonPressed,
+                                        width = dWidth)
+
+        self.__RegReadButton.grid(column=dColumn, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+                        # generate the 'reg write' button.
+      def uiRegWrite(self,dColumn,dRow,dWidth):
+        self.__RegWriteButton = Button(self.__frame, text="REG WRITE", 
+                                        command=self.selectRegWriteButtonPressed, 
+                                        width = dWidth)
+
+        self.__RegWriteButton.grid(column=dColumn, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+                        # generate the mm-read button.
+      def uimmRead(self,dColumn,dRow,dWidth):
+        self.__mmReadButton = Button(self.__frame, text="MM READ", 
+                                        command=self.selectmmReadButtonPressed, 
+                                        width = dWidth)
+
+        self.__mmReadButton.grid(column=dColumn, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+                        # generate the 'mm write' button.
+      def uimmWrite(self,dColumn,dRow,dWidth):
+        self.__mmWriteButton = Button(self.__frame, text="MM WRITE", 
+                                        command=self.selectmmWriteButtonPressed, 
+                                        width = dWidth)
+
+        self.__mmWriteButton.grid(column=dColumn, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+      def uiProg(self,dColumn,dRow,dWidth): # generate the 'program' button.
+        self.__ProgButton = Button(self.__frame, text="PROGRAM", 
+                                        command=self.selectProgButtonPressed, 
+                                        width = dWidth)
+
+        self.__ProgButton.grid(column=dColumn, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+                        # generate the 'mm dump' button.
+      def uimmDump(self,dColumn,dRow,dWidth):
+        self.__mmWriteButton = Button(self.__frame, text="DUMP", 
+                                        command=self.selectmmDumpButtonPressed, 
+                                        width = dWidth)
+
+        self.__mmWriteButton.grid(column=dColumn, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+      def uiStep(self,dColumn,dRow,dWidth): # generate the 'step' button.
+        self.__StepButton = Button(self.__frame, text="STEP", 
+                                        command=self.selectStepButtonPressed, 
+                                        width = dWidth)
+
+        self.__StepButton.grid(column=dColumn, row=dRow, sticky=(W))
+#-----------------------------------------------#-------------------------------
+      def uiRun(self,dColumn,dRow,dWidth):  # generate the 'run' button.
+        self.__runButton = Button(self.__frame, text="RUN", 
+                                      command=self.selectRunButtonPressed,width = dWidth)
+
+        self.__runButton.grid(column=dColumn, row=dRow, sticky=(E))
+#-----------------------------------------------#-------------------------------
+      def uiTest(self,dColumn,dRow,dWidth): # generate the 'test' button.
+        self.__testButton = Button(self.__frame, text="TEST", 
+                                      command=self.selectTestButtonPressed,width = dWidth)
+
+        self.__testButton.grid(column=dColumn, row=dRow, sticky=(E))
+#-----------------------------------------------#-------------------------------
+      def uiExit(self,dColumn,dRow,dWidth): # generate the 'exit' button.
+
+        self.__isRunning = 0        # end the running thread.
+        sleep(2.0)              # give thread time to stop.
+
+        self.__exitButton = Button(self.__frame, text="EXIT", 
+                                       command=sys.exit,width = dWidth)
+
+        self.__exitButton.grid(column=dColumn, row=dRow, sticky=(E))
+#-----------------------------------------------#-------------------------------
+#     BEGIN EXECUTE-WHEN-BUTTON-PRESSED CODE#===============================
+#-----------------------------------------------#-------------------------------
+      def selectConnectButtonPressed(self): # execute CONNECT.
+        if (self.__connected == 0):
+          self.__iUSB = mmUSBserial(idVendor=0x1234, idProduct=0x0006)
+          self.__connected = 1
+          self.__connectButton["text"] = "DISCONNECT"
+          self.__connectButton["background"] = self.__frame.cget("background")
+        else:
+          del(self.__iUSB)
+          self.__connected = 0
+          self.__connectButton["text"] = "CONNECT"
+          self.__connectButton["background"] = "RED"
+#-----------------------------------------------#-------------------------------
+      def selectRegReadButtonPressed(self): # REG READ button has been pressed.
+        self.refreshUI()            # ensure proper text formats.
+
+
+                        # read R0.
+        self.__iUSB.write(self.buildReadRegisterCommand("0"))
+        fetchTextR0 =     self.__iUSB.read()
+        hexTextR0   =     self.formatRegValPayload(fetchTextR0)
+        self.__R0Entry.delete(0,99)
+        self.__R0Entry.insert(0,hexTextR0)
+
+                        # read R1.
+        self.__iUSB.write(self.buildReadRegisterCommand("1"))
+        fetchTextR1 =     self.__iUSB.read()
+        hexTextR1   =     self.formatRegValPayload(fetchTextR1)
+        self.__R1Entry.delete(0,99)
+        self.__R1Entry.insert(0,hexTextR1)
+
+
+                        # read R2.
+        self.__iUSB.write(self.buildReadRegisterCommand("2"))
+        fetchTextR2 =     self.__iUSB.read()
+        hexTextR2   =     self.formatRegValPayload(fetchTextR2)
+        self.__R2Entry.delete(0,99)
+        self.__R2Entry.insert(0,hexTextR2)
+
+                        # read R3.
+        self.__iUSB.write(self.buildReadRegisterCommand("3"))
+        fetchTextR3 =     self.__iUSB.read()
+        hexTextR3   =     self.formatRegValPayload(fetchTextR3)
+        self.__R3Entry.delete(0,99)
+        self.__R3Entry.insert(0,hexTextR3)
+
+
+                        # read Program Counter.
+        self.__iUSB.write(self.buildReadRegisterCommand("4"))
+        fetchTextPC =     self.__iUSB.read()
+        hexTextPC   =     self.formatRegValPayload(fetchTextPC)
+        self.__PCEntry.delete(0,99)
+        self.__PCEntry.insert(0,hexTextPC)
+
+                        # read Instruction Register high.
+        self.__iUSB.write(self.buildReadRegisterCommand("5"))
+        fetchTextIRH =    self.__iUSB.read()
+        hexTextIRH   =    self.formatRegValPayload(fetchTextIRH)
+
+
+                        # read Instruction Register low.
+        self.__iUSB.write(self.buildReadRegisterCommand("6"))
+        fetchTextIRL =    self.__iUSB.read()
+        hexTextIRL   =    self.formatRegValPayload(fetchTextIRL)
+        hexTextIR    = hexTextIRH + hexTextIRL[2:]
+
+
+        self.__IREntry.delete(0,99)     # 2-byte IR content to UI.
+        self.__IREntry.insert(0,hexTextIR)
+
+#----
+        self.refreshUI()            # ensure proper text formats
+#-----------------------------------------------#-------------------------------
+      def selectmmReadButtonPressed(self):  # MM READ button has been pressed.
+        self.refreshUI()            # ensure proper text formats.
+
+        transmitmmADRText = self.formatByteStringForTransmit(self.__mmADREntry.get())
+        commandText = self.buildReadMMCommand(transmitmmADRText)
+
+        self.__iUSB.write(commandText)
+
+        fetchTextmmVAL = self.__iUSB.read()
+
+        buildHextmmVALString = fetchTextmmVAL[3:7]
+
+        self.__mmVALEntry.delete(0,99)
+        self.__mmVALEntry.insert(0,buildHextmmVALString)
+#----
+        self.selectRegReadButtonPressed()   # because registers are affected.
+        self.refreshUI()            # ensure proper text formats
+#-----------------------------------------------#-------------------------------
+#     before writing the register values currently displayed in the UI,
+#     this method will first run that data through a formatter, so that
+#     the data is transformed into '0x##' format.  this is convenient for
+#     the user.  for example, the user can type '12' in a register entry
+#     form, press the 'REG WRITE' button, and that data will be reformatted
+#     to appear as '0x12'.
+
+      def selectRegWriteButtonPressed(self):# REG WRITE button has been pressed.
+
+        self.refreshUI()            # ensure proper text formats.
+#----
+                        # place those values in the
+                        # standard format.
+        R0Val = self.formatByteStringForTransmit(self.__R0Entry.get())
+        R1Val = self.formatByteStringForTransmit(self.__R1Entry.get())
+        R2Val = self.formatByteStringForTransmit(self.__R2Entry.get())
+        R3Val = self.formatByteStringForTransmit(self.__R3Entry.get())
+        PCVal = self.formatByteStringForTransmit(self.__PCEntry.get())
+        IRVal = self.formatWordStringForTransmit(self.__IREntry.get()) 
+#----
+                        # write those values to the CPU.
+        self.__iUSB.write(self.buildWriteRegisterCommand("0",R0Val))
+        self.__iUSB.write(self.buildWriteRegisterCommand("1",R1Val))
+        self.__iUSB.write(self.buildWriteRegisterCommand("2",R2Val))
+        self.__iUSB.write(self.buildWriteRegisterCommand("3",R3Val))
+        self.__iUSB.write(self.buildWriteRegisterCommand("4",PCVal))
+        self.__iUSB.write(self.buildWriteIRCommand      (    IRVal))
+#-----------------------------------------------#-------------------------------
+#     before writing the main-memory values currently displayed in the UI,
+#     this method will first run that data through a formatter, so that
+#     the data is transformed into '0x##' or '0x####' format.  
+#     this is convenient for the user.  
+#     for example, the user can type '12' in the mmADR entry
+#     form, press the 'MM WRITE' button, and that data will be reformatted
+#     to appear as '0x12'.
+
+      def selectmmWriteButtonPressed(self): # mm WRITE button has been pressed.
+
+        self.refreshUI()            # ensure proper text formats.
+
+                        # obtain mm values currently
+                        # displayed in the UI.
+        self.__transmitmmADRText = self.__mmADREntry.get()
+        self.__transmitmmVALText = self.__mmVALEntry.get()
+
+                        # place those values in the
+                        # standard format.
+        mmADRVAL = self.formatByteStringForTransmit(self.__mmADREntry.get())
+        mmVALVal = self.formatWordStringForTransmit(self.__mmVALEntry.get())
+
+                        # write those values to the CPU.
+        self.__iUSB.write(self.buildWriteMMCommand(mmADRVAL,mmVALVal))
+
+        self.selectRegReadButtonPressed()   # because registers are affected.
+#-----------------------------------------------#-------------------------------
+      def selectProgButtonPressed(self):    # Program button has been pressed.
+
+                        # ask user for program source file
+                        # name using a dialog.
+        fileName = tkFileDialog.askopenfilename(defaultextension='.txt')
+
+        print("memory load started.")   # announce to user.
+        self.progamMainMemory(fileName) # main part of programming.
+        print("memory load completed.") # announce to user.
+#-----------------------------------------------#-------------------------------
+      def selectmmDumpButtonPressed(self):  # MM dump button has been pressed.
+
+                        # obtain file-to-write-to name
+                        # from user, using a dialog.
+        fileName = tkFileDialog.asksaveasfilename(defaultextension='.txt')
+
+        print("memory dump started.")   # announce to user.
+        self.dumpMainMemory(fileName)   # dump main memory to file.
+        print("memory dump completed.") # announce to user.
+#-----------------------------------------------#-------------------------------
+      def selectStepButtonPressed(self):    # STEP button has been pressed.
+        self.__iUSB.write("50000000")   # the command code.
+        self.selectRegReadButtonPressed()   # monitor the result.
+#-----------------------------------------------#-------------------------------
+      def selectRunButtonPressed(self):     # RUN/STOP button has been pressed.
+
+        if (self.__isRunning == 0):     # start high speed run.
+          self.__isRunning = 1
+          self.__runButton["text"] = "SLOW"
+          self.t = threading.Thread(target=self.doRun)
+          self.t.start()
+
+        elif (self.__isRunning == 1):   # switch to a slower run.
+          self.__isRunning = 2
+              self.__runButton["text"] = "STOP"
+
+        else:               # stop the CPU.
+          self.__isRunning = 0
+          self.__runButton["text"] = "RUN"
+#-----------------------------------------------#-------------------------------
+      def selectTestButtonPressed(self):    # TEST/STOP button has been pressed.
+
+        if (self.__testRunning == 0):   # start test.
+          self.__testRunning = 1
+          self.__testButton["text"] = "STOP TEST"
+          self.t = threading.Thread(target=self.doTest)
+          self.t.start()
+
+
+        else:               # stop test.
+          self.__testRunning = 0
+          self.__testButton["text"] = "TEST"
+#-----------------------------------------------#-------------------------------
+#     BEGIN UTILITY CODE.           #===============================
+#-----------------------------------------------#-------------------------------
+                        # guarantee 0x## format.
+      def formatByteStringForDisplay(self, byteText):   
+    
+        xIndex = byteText.find("x")     # eliminate any 0x, 0X prefix.
+        XIndex = byteText.find("X")
+
+        theXindex   = 0
+        if (xIndex >= 0): theXindex = xIndex + 1
+        if (XIndex >= 0): theXindex = XIndex + 1
+
+        buildText = byteText[theXindex:]    # any 0x, 0X prefix gone.
+
+                        # build-out leading 0's.
+        if (len(buildText) == 0): buildText = "0" + buildText
+        if (len(buildText) == 1): buildText = "0" + buildText
+
+                        # truncate leading characters.
+        if (len(buildText)  > 2): buildText = buildText[-2:]
+
+        buildText = "0x" + buildText    # add leading 0x.
+
+        return(buildText)           # 0x## format returned.
+#-----------------------------------------------#-------------------------------
+                        # guarantee 0x#### format.
+      def formatWordStringForDisplay(self, wordText):   
+    
+        xIndex = wordText.find("x")     # eliminate any 0x, 0X prefix.
+        XIndex = wordText.find("X")
+
+        theXindex   = 0
+        if (xIndex >= 0): theXindex = xIndex + 1
+        if (XIndex >= 0): theXindex = XIndex + 1
+
+        buildText = wordText[theXindex:]    # any 0x, 0X prefix gone.
+
+                        # build-out leading 0's.
+        if (len(buildText) == 0): buildText = "0" + buildText
+        if (len(buildText) == 1): buildText = "0" + buildText
+        if (len(buildText) == 2): buildText = "0" + buildText
+        if (len(buildText) == 3): buildText = "0" + buildText
+
+
+                        # truncate leading characters.
+        if (len(buildText)  > 4): buildText = buildText[-4:]
+
+        buildText = "0x" + buildText    # add leading 0x.
+
+        return(buildText)           # 0x## format returned.
+#-----------------------------------------------#-------------------------------
+                        # guarantee ## format.
+      def formatByteStringForTransmit(self, byteText):
+        buildText = self.formatByteStringForDisplay(byteText)
+        buildText = buildText[-2:]
+        return(buildText)
+#-----------------------------------------------#-------------------------------
+                        # guarantee #### format.
+      def formatWordStringForTransmit(self, wordText):
+        buildText = self.formatWordStringForDisplay(wordText)
+        buildText = buildText[-4:]
+        return(buildText)
+#-----------------------------------------------#-------------------------------
+      def refreshUI(self):          # reformat UI text.
+
+                        # copy-in current form contents.
+        originalR0Entry    = self.__R0Entry.get()
+        originalR1Entry    = self.__R1Entry.get()
+        originalR2Entry    = self.__R2Entry.get()
+        originalR3Entry    = self.__R3Entry.get()
+        originalPCEntry    = self.__PCEntry.get()
+        originalIREntry    = self.__IREntry.get()
+        originalmmADREntry = self.__mmADREntry.get()
+        originalmmVALEntry = self.__mmVALEntry.get()
+
+                            # reformat form contents.
+        newR0Entry    = self.formatByteStringForDisplay(originalR0Entry)
+        newR1Entry    = self.formatByteStringForDisplay(originalR1Entry)
+        newR2Entry    = self.formatByteStringForDisplay(originalR2Entry)
+        newR3Entry    = self.formatByteStringForDisplay(originalR3Entry)
+        newPCEntry    = self.formatByteStringForDisplay(originalPCEntry)
+        newIREntry    = self.formatWordStringForDisplay(originalIREntry)
+
+        newmmADREntry = self.formatByteStringForDisplay(originalmmADREntry)
+        newmmVALEntry = self.formatWordStringForDisplay(originalmmVALEntry)
+
+                        
+        self.__R0Entry.   delete(0,99)  # clear form contents.
+        self.__R1Entry.   delete(0,99)
+        self.__R2Entry.   delete(0,99)
+        self.__R3Entry.   delete(0,99)
+        self.__PCEntry.   delete(0,99)
+        self.__IREntry.   delete(0,99)
+        self.__mmADREntry.delete(0,99)
+        self.__mmVALEntry.delete(0,99)
+
+                        # update form contents.
+        self.__R0Entry.   insert(0,newR0Entry)
+        self.__R1Entry.   insert(0,newR1Entry)
+        self.__R2Entry.   insert(0,newR2Entry)
+        self.__R3Entry.   insert(0,newR3Entry)
+        self.__PCEntry.   insert(0,newPCEntry)
+        self.__IREntry.   insert(0,newIREntry)
+        self.__mmADREntry.insert(0,newmmADREntry)
+        self.__mmVALEntry.insert(0,newmmVALEntry)
+#-----------------------------------------------#-------------------------------
+                        # build the command string for
+                        # reading a value from a CPU register.
+      def buildReadRegisterCommand(self,regNum):
+
+        commandText = ""            # build command for read register.
+        commandText = commandText + "2" # command-code.
+        commandText = commandText + regNum  # register number.
+        commandText = commandText + "0000000000000"
+        return(commandText)
+#-----------------------------------------------#-------------------------------
+                        # build the command-string for
+                        # writing a value to a CPU register.
+      def buildWriteRegisterCommand(self,regNum,regVal):
+
+        commandText = ""
+        commandText = commandText + "1" # command-code.
+        commandText = commandText + regNum  # register.
+        commandText = commandText + regVal  # content.
+        commandText = commandText + "00000000000"
+        return(commandText)
+#-----------------------------------------------#-------------------------------
+                        # build the command-string for
+                        # writing a value to the IR.
+      def buildWriteIRCommand(self,regVal):
+
+        commandText = ""
+        commandText = commandText + "6" # command-code.
+        commandText = commandText + "5" # actually a placeholder.
+        commandText = commandText + regVal  # content.
+        commandText = commandText + "000000000"
+        return(commandText)
+#-----------------------------------------------#-------------------------------
+                        # build the command-string for
+                        # writing a main-memory value.
+      def buildWriteMMCommand(self,mmADR,mmVAL):
+    
+        commandText = ""
+        commandText = commandText + "3" # command-code.
+        commandText = commandText + mmADR   # address.
+        commandText = commandText + mmVAL   # value.
+        commandText = commandText + "00000000"
+        return(commandText)
+#-----------------------------------------------#-------------------------------
+      def buildReadMMCommand(self,mmADR):   # build read-mm command-string.
+          commandText = ""          # build command for read main-memory.
+          commandText = commandText + "4"   # command-code.
+          commandText = commandText + mmADR
+          commandText = commandText + "000000000000"
+          return(commandText)
+#-----------------------------------------------#-------------------------------
+                        # extract reg value payload.
+      def formatRegValPayload(self,messageVector):
+        buildHex = "0x" + messageVector[2:4]
+        return(buildHex)
+#-----------------------------------------------#-------------------------------
+      def progamMainMemory(self,progFile):  # core of loading program to MM.
+
+        hFile = open(progFile, 'r')
+        fileLineList = hFile.readlines()    # read file into a list.
+        hFile.close()           # close the file.
+
+                        # load '0x12 0x3456' memory content
+                        # format, into a list.
+        for listIndex in range(0, len(fileLineList)):
+          addressStartIndex = fileLineList[listIndex].find("0x") + 2
+          dataStartIndex    = fileLineList[listIndex].find("0x", addressStartIndex)   + 2
+          progAddress = fileLineList[listIndex][addressStartIndex : addressStartIndex + 2]
+          progAddress = format(listIndex,'02x')
+          progData    = fileLineList[listIndex][dataStartIndex    : dataStartIndex    + 4]
+          commandText = self.buildWriteMMCommand(progAddress,progData)
+              self.__iUSB.write(commandText)
+          print(fileLineList[listIndex][0:len(fileLineList[listIndex])-1])
+          sleep(self.__sleepVal)
+#-----------------------------------------------#-------------------------------
+      def dumpMainMemory(self,dumpFile):    # core of dumping MM to file.
+
+        hFile = open(dumpFile, 'w')
+
+        for loopIndex in range(0, 256): # traverse all of main-memory.
+          transmitmmADRText = "{}".format(hex(loopIndex))
+              transmitmmADRText = transmitmmADRText[2:]
+              if (len(transmitmmADRText) == 1): transmitmmADRText = "0" + transmitmmADRText
+          commandText = self.buildReadMMCommand(transmitmmADRText)
+          self.__iUSB.write(commandText)
+          fetchTextmmVAL = self.__iUSB.read()
+          buildHextmmVALString = fetchTextmmVAL[3:7]
+          buildHexIndex = hex(loopIndex)
+          buildHexIndex = buildHexIndex[2:]
+          if (len(buildHexIndex) == 1): buildHexIndex = "0" + buildHexIndex
+          buildHexIndex = "0x" + buildHexIndex
+          dumpString = "  {}  0x{}\n".format(buildHexIndex,buildHextmmVALString)
+          hFile.write(dumpString)
+          print(dumpString[0:len(dumpString)-1])
+          sleep(self.__sleepVal)
+
+        hFile.close()           # close the dump file.
+#-----------------------------------------------#-------------------------------
+#     BEGIN THREADED CODE.          #===============================
+#-----------------------------------------------#-------------------------------
+      def doRun(self):          # drives the CPU running.
+        while(self.__isRunning):
+          self.selectStepButtonPressed()
+          self.__masterWidget.update_idletasks()    
+              if (self.__isRunning == 2): sleep(1.0)    
+#-----------------------------------------------#-------------------------------
+#     the test consists of loading the add-list program into main memory,
+#     running it, dumping the result to a file, and comparing that file
+#     to the expected result.
+
+      def doTest(self):         # drives the test.
+        while(self.__testRunning):
+                        # load program into main memory.
+          self.progamMainMemory("prog_add_list.txt")
+
+                        # clear instruction register.
+          self.__iUSB.write(self.buildWriteIRCommand("0000"))
+
+                        # rewind program counter.
+          PCVal          = self.formatByteStringForTransmit("0")
+          writePCcommand = self.buildWriteRegisterCommand("4",PCVal)
+          self.__iUSB.write(writePCcommand)
+          self.selectRegReadButtonPressed()
+
+
+          for stepIndex in range(0, 196):   # step through program.
+            self.selectStepButtonPressed()
+
+                        # dump result to file.
+          self.dumpMainMemory  ("dump_test.txt")
+
+                        # build and run test commands.
+          self.__testIter = self.__testIter + 1 
+          iterationText = "test iteration {}".format(self.__testIter)
+          iterationText = "echo '" + iterationText + "' >> testlog.txt"
+          os.system("echo ============================ >> testlog.txt")
+          os.system("date >> testlog.txt")
+          os.system(iterationText)
+          os.system("echo 'compare dump_test.txt against dump_add_list.txt' >> testlog.txt")
+          os.system("diff dump_add_list.txt dump_test.txt >> testlog.txt")
+
+          self.__masterWidget.update_idletasks()    
+#===============================================#===============================
+
+
+
+
+
+
+
+
+
+
+
+
+