embedded RTOS class project.

Fork of RTOS_project by Mike Moore

mmPython/mmUI.txt

Committer:
gatedClock
Date:
2013-09-17
Revision:
4:e3887e314551
Parent:
0:8e898e1270d6

File content as of revision 4:e3887e314551:

#!/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.  3 works.

            
            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.

                                                # real all registers.
            self.__iUSB.write(self.buildReadAllRegisterCommand())
            messageVector =   self.__iUSB.read()

                                                # parse-out the register entries.
            hexTextR0     = "0x" + messageVector[ 1: 3]
            hexTextR1     = "0x" + messageVector[ 3: 5]
            hexTextR2     = "0x" + messageVector[ 5: 7]
            hexTextR3     = "0x" + messageVector[ 7: 9]
            hexTextPC     = "0x" + messageVector[ 9:11]
            hexTextIR     = "0x" + messageVector[11:15]


            self.__R0Entry.delete(0,99)         # R0 to UI.
            self.__R0Entry.insert(0,hexTextR0)

            self.__R1Entry.delete(0,99)         # R1 to UI.
            self.__R1Entry.insert(0,hexTextR1)

            self.__R2Entry.delete(0,99)         # R2 to UI.
            self.__R2Entry.insert(0,hexTextR2)

            self.__R3Entry.delete(0,99)         # R3 to UI.
            self.__R3Entry.insert(0,hexTextR3)

            self.__PCEntry.delete(0,99)         # PC to UI.
            self.__PCEntry.insert(0,hexTextPC)

            self.__IREntry.delete(0,99)         # IR 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
                                                # reading all CPU register values.
          def buildReadAllRegisterCommand(self):

            commandText = ""                    # build command for read register.
            commandText = commandText + "7"     # command-code.
            commandText = commandText + "00000000000000"
            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()    
#===============================================#===============================