For the first assignment, the class is divided into small groups and each group is responsible for hand-assembling ten instructions in the control store. By requiring that all don't-care bits be zero, there is only one correct answer for each word of microcode. The students hand in their results by email and these answers are collected into a single file to form the control store input for the simulator.
The simulator assignment consists of writing a basic simulator which allows for single stepping at each of three levels: Mic-1 subcycle, Mic-1 cycle, and Mac-1 instruction cycle. The simulator program essentially consists of a loop which, aside from handling standard input, calls the four procedures to handle the Mic-1 subcycles. For example, subcycle one consists of taking the element from the control store array indexed by the MPC and decoding it. The decoding involves shifting and masking so that each bit field of the MIR can be stored in the appropriate field of an MIR structure. The simulator shows each field on the display by calling a routine such as ani_set_mir_A_value(value,reg).
The basic simulator assignment is divided into milestones. The first milestone consists of writing a main program which just calls the initialize_animator routine and is executed with its standard output redirected to the animator. These few lines of code allow the students to see how easy it is to bring up the graphical interface. The second milestone consists of setting up and initializing the data structures used for storing the state of the Mic-1 machine and sending the initial values of the sixteen registers to the animator. At this point students have written very little code, but they can see how the animation will progress. They can try out several of the routines for controlling the graphical display and get a feel for what will be involved in the simulation. The milestones progress in simple steps until the entire simulator is complete.
The simulator takes simple input commands for single stepping and for turning on and off the dynamic updating of the display. Even with fast hardware, it takes several seconds to show a full Mac-1 instruction cycle so for testing more than a few Mac-1 instructions, it is convenient to not show the detailed execution at each Mic-1 subcycle. The simulator can execute about a thousand Mac-1 instructions per second with the display updating turned off when run on a low-end Sun workstation.
The Mac-1 assembly language is cumbersome for manipulating arrays since it does not have indirect addressing except through the stack pointer and accumulator. In the next assignment students add a number of instructions for indexed addressing. The new assembly language is called the Mac-1a. The students are given a Mic-1 assembler at this point and told to modify the control store to implement the new instructions. The opcode encoding for the new instructions is left to the students and they are challenged to find the most efficient encoding and control store program which maintains binary compatibility with the old machine. This leads to a good discussion of the consequences of binary compatibility over several generations. They also make a few minor modifications to their simulator to keep track of the number of Mic cycles and Mac instructions executed. Since the animator displays the decoded instruction register, some routines are included so that the student's simulators can communicate the information about the new Mac instructions to the animator.
One of the problems with the original simulator was the display of the Mac-1 memory. It was left to the students to display this memory with an appropriate command to their simulator. This was done with text sent to standard error and was independent of the graphical display. Towards the end of the semester, we modified the animator display so it could show a part of the Mac memory as well as the cycle and instruction counts. The new animator display is shown in Figure 3.
Figure 3: The animator display for the second version of the simulator.