Mythsim Assembler CS 398 Project By Scott Price, Spring 2005 (See notes at the bottom for running the program) For my CS398 independent design and research project I wrote a pseudo-assembler for Mythsim, the visual microcode simulator. In order to use Mythsim, the user has to create a µcode file and a mem file. The µcode file consists of instructions and their definitions. For example, if a user wanted to have an addition instruction, they would have to define it, in the µcode file, in this way: opcode[x]: ri_sel, rj_sel, rk_sel, alu_sel=ADD, goto fetch0; (Where x can be any number between 0 and 63) Additionally, the user has to create a mem file which consists of instructions written in binary. The mem file is essentially used to test the µcode file; to make sure that the instructions defined in the µcode file are working as desired. The mem file instructions are written in binary and look something like this: 0: 00000000 1: 01001001 2: 01101111 (Mythsim requires that line numbers accompany each line.) Because Mythsim requires not only that the instructions be written in binary, but that line numbers appear next to each line of code, the mem file becomes a less than trivial and time consuming task. My project remedies these “problems” by allowing the user to write assembly instructions with out having to worry about binary conversions or line numbers. In order to use my program the user has to modify their µcode file to include special comments that indicate to my program the specifics of each instruction. The special comment should have the following format: //@add ri, rj, rk The format can be broken down into four parts: 1. “//” The two forward slashes indicate to Mythsim that this line is a comment. 2. “@” This symbol is required by my program, and is used to differentiate Mythsim comments from comments intended for my program. 3. “add” This is the name (or mnemonic) that the user gives to the instruction and how they will refer to the instruction in the mem file. 4. “ri, rj, rk” These are the operands that the instruction will use. Instructions can have no operands, or several. When there is more than one, they must be separated by commas. Additionally, their order matters; if the instruction is defined with “ri, rj” then in the mem file, the values must appear in that order. There are seven classes that make up the entire assembler program: AssemblyInstructionFormat BinaryInstruction BinaryInstruction4 BinaryInstruction8 BinaryInstructionExtended FileChooser MythsimAssembler AssemblyInstructionFormat This class is used to keep track of the information that describes an assembly instruction (This information comes from the µcode file.) The “main” method of this class is findOperands(). This method determines which operands a given instruction requires and in what order they appear. The ordering of the operands is important, as the values in the mem file will be specified in the same order as the operands in the µcode file. BinaryInstruction This class is used to group all the information that all binary instructions have in common. This includes the opcode, “ri” register and a few other internal parameters. As a result, this class is abstract because it doesn’t represent a complete binary instruction. There are two methods that are also abstract, and are meant to be implemented by child classes. The setOperand() method is used to set the value of a specific operand. This method is abstract because different child classes will have different operands, thus, they must define this method to set their respective operands. The second abstract method is generate(). This method “generates” the actual binary instruction (as a string) using all the information from a BinaryInstruction, as well as information from a child class. Again, since not all child classes will have the same information this method must be defined by each child class. BinaryInstruction4 This class extends the BinaryInstruction class. In addition to the information in the parent class, this class stores the “rj” and “rk” registers, as well as the “const_4” constant. As required, this class defines the abstract methods of the parent class: setOperand() and generate(). BinaryInstruction8 This class extends the BinaryInstruction class. In addition to the information in the parent class, this class stores the “const_8” constant. As required, this class defines the abstract methods of the parent class: setOperand() and generate(). BinaryInstructionExtended This class extends the BinaryInstruction class. In addition to the information in the parent class this class stores the “rj” and “rk” registers as well the “const_4” and “const_8” constants. This class differs from BinaryInstruction4 and BinaryInstruction8 in that it allows the user to specify on which lines each operand should appear. The user specifies this in the µcode file by using brackets: []. Here is an example: //@addm ri[4], a[3] In this example, the “ri” value would appear on the fourth line of the binary instruction. Additionally, this class allows this user to specify additional constants, as long as they appear on different lines. The syntax for this can be seen in the above example where “a[3]” indicates that a constant should appear on the third line of the binary instruction. The letter “a” is simply a place holder, and any lower or upper case letter is valid. FileChooser This class is simply used for displaying the “select a file” dialog, which allows the user to navigate to their µcode and mem files. MythsimAssembler This class is the controller and the logic for the whole program. The main method creates a new MythsimAssembler object, and after prompting the user for the µcode, mem and output files, it calls the readUCodeFile() method and then the readMemFile() method. The readUCodeFile() reads the µcode file twice. The first time the file is read, it looks for labels. Labels simply allow the user another convenience when writing the mem file, as they let the user refer to other lines of code by name. The second pass of the µcode file actually starts to create AssemblyInstructionFormat objects. Once the µcode file is read, the program moves on to the mem file. It first extracts the assembly instruction name/mnemonic from the file and attempts to locate an AssemblyInstructionFormat object with that name/mnemonic, which is stored in an ArrayList. Upon successfully finding an AssemblyInstructionFormat object, the program then begins to extract the values from the mem file and assign them to the proper operands in a class derived from the BinaryInstruction class. Running the Program To run the program the user will run the jar file. They will then be prompted with a “File Open” dialog which will allow them to specify their µcode file. Immediately upon clicking the “Open” button, another “File Open” dialog appears, this time requesting the mem/asm file. Finally, an input dialog will appear and allow the user to type in the path of their desired output file. The user will then open the newly created output. If all no errors were encountered, then the mem file will contain the appropriate binary code. If certain errors were detected, they will be displayed in the mem file. (Notes: The asm/mem file may have blank lines as well as comments, which must begin with the “//” characters. Also, the order of the instructions in the µcode file matters; Opcode numbers are assigned from the top down beginning with 0. This has little effect on the user’s interaction with the program, however, if opcodes are being skipped in the µcode file, they should still be accompanied by a “//@” comment with a dummy name/mnemonic such as “//@skip1”, or something equivalent (and unique), so that the opcode numbers assigned to instructions in the generated mem file correspond to the opcode numbers specified in the µcode file.)