Project, Phase 1

CMSC 411 / Olano, Fall 2015

Over the remainder of the semester, you will be working in project groups of 3-4 to simulate a robot control processor. The first phase is to create a functional simulator for your robot's machine code. This simulates the operations without regard to the timing or how it would be implemented in a processor. For this phase, you will write C or C++ code to decode your machine code and use C operations to simulate its behavior.

Assembler Extensions

Decide who from your group had the best assembler for homework 1. You will extend this assember with one new robot control instruction type (C-type) for opcode 010011. So you will use R-type for opcode 000000, C-type for 010011, J-type for 00001x, and I-type for anything else.

R-type opcode (6b) rs (5b) rt (5b) rd (5b) sh (5b) func (6b)
I-type opcode (6b) rs (5b) rd (5b) immediate (16b)
J-type opcode (6b) address (26b)
C-type opcode (6b) Cfn (5b) rd (5b) immediate (16b)

The function is specified by a 5-bit Cfn field with the following instructions:

Cfn Instruction Meaning
00000 spd imm($rd) set robot speed to $rd+imm
00001 rot imm($rd) set robot rotation rate to $rd+imm
00010 ascn $rd scan for objects, returns the angle to closest object within the scanner field of view in $rd
00011 dscn $rd scan for objects, returns the distance to closest object within the scanner field of view in $rd
00100 fir imm($rd) fire at point $rd+imm from the current position

Code, Memory and Registers

You will create a new C program for this phase of the project which will have your assembled machine code compiled in. Assuming your program was called rasm, you might run your assembler like this to generate comma-separated hex-format machine code output in code.h:

rasm assember.asm code.h

You can then compile this machine code file into your C or C++ code like this, assuming 1024 words of total memory for your robot:

int mem[1024] = {
#include "code.h"

Your registers are also easily represented by an array:

int reg[32];

And, of course you'll need a variable for the current program counter.

int PC;


Start simulating at address 0. For each instruction you execute, you will need to get the instruction at the current program counter (mem[PC]) then update the program counter. Based on the instruction opcode figure out the instruction format and decode it into register numbers, immediate values, etc. Then execute C code to perform the operation. You only need to simulate the instructions from homework 1 and the robot control instructions.

Before each instruction, you should wait for the user to press enter once with a line like this:

fgets(line, sizeof(line), stdin);

After you execute the instruction, you must print one robot output line. These robot output lines should be the only external output from your program. The commands are:

Output Line Response Comments
M <rate> none Set the robot movement speed to <rate> feet per second. Actual movement clamped to be between -6 and 6
R <rate> none Set the robot rotation speed to <rate> degrees per second. Actual rotation will be clamped between -90 and 90
A distance Angular scan in the current direction. Responds with the angle to the first object (living or dead robot, or wall).
D distance Distance scan in the current direction. If the first thing seen is another living robot, responds with the distance in feet. If it is a wall or dead robot, responds with a negative distance.
F <distance> none Fire in the current direction at a point <distance> feet away. Any robot within one foot of the shot will be killed. Negative values are clamped to 0. A fire distance ≤1 will kill your own robot.
N none No robot command this instruction

The scan commands (A and D) are the only one with a response. If you issue a scan command, you should read the next line (with fgets again), and assign the signed integer returned into the appropriate register. This is separate from the fgets that tells you to execute the next instruction.


You can run your robot instance on the command line. Hit enter for each instruction to execute. If you see an "A" or "D" line output, enter a line with a number, then press enter again for the next instruction. To ensure your robot will work with the driver program, debugging prints should go to stderr (or cerr if using C++ fstreams), not stdout/cout.

To simulate a fight between several robots, create a file named "robots.txt". Each line of this file should be a robot name (for identification), followed by the robot program and any arguments. Robot names, program names or paths, and arguments cannot contain spaces. For a console version on the gl.umbc systems, run this command in the directory containing your robot program and robots.txt file:

~olano/robotarena/RobotDriver -p

With the -p option, it stops after each instruction and waits for you to hit enter. The printed output gives the location and direction of each robot followed by any C-type robot action issued that instruction.

The RobotDriver program also supports a simple graphic display of the robots as a web application, but to view this from the GL systems, we need to use ssh port tunneling. First, each student will need to use a unique port number on the GL system. Also, low-number ports are reserved, so you should choose a port number in the range 49152-65535. If you try one and it says it is in use, choose another. To set up the tunneling from a linux or mac computer, use the following from your terminal window, with your username and unique port number replacing <user> and <port>.

ssh <user> -L8080:localhost:<port>

On Windows, you can right-click on the desktop and select the option to create a new shortcut. A dialog box will pop up where you can enter the shortcut file location. Just type this, once again with your unique port number in place of <port>. Once you create this shortcut, you can use it to connect to the GL linux servers with your port forwarded.

"C:\Program Files (x86)\TeraTerm\ttssh.exe" /ssh /ssh-L8080:localhost:<port>

Either way gives you a normal GL server terminal window, where you can do any of the things you normally would. In addition, if you run

~olano/robotarena/RobotDriver -w <port>

Then visit the web page "localhost:8080" using a browser on your local PC, you should see a page with a square arena with several robots. You can go one step at a time or let them run to fight it out. If you have problems with these directions, come see me during office hours. Though being able to see the robots fight may be helpful to see if they're working, getting this remote ssh-tunneled version working for your system is not necessary for you to get full credit on the project. If the terminal version works for you, I will be able to run the web version for myself.

Working and Submitting

Choose a team name. It should be purely alphanumeric (no spaces). Send me a single email per team with the team name and members no later than Wednesday, September 16th. I will create a git respository directory for your team.

You can use git to help with your team collaboration. If one team member commits and pushes a change, the other team members will be able to get it with git pull. Non-overlapping changes will be automatically merged by git, so you will still need to at least coordinate enough to not work on the same section of code at the same time. Overlapping changes will create a conflict, which will give you a file with the different versions marked after the update. If that happens, you will need to manually figure out the code that should be there to resolve the conflict, then re-commit the resolved version. You'll want to avoid these conflicts as much as you can. I recommend pushing often to limit the scope of merges.

In any case, you should commit your work by the phase 1 deadline. Include a short file named "readme.txt" that describes how to build and run your program, as well as a description of any known problems or bugs.