Due September 29, 2009

General expectations

The goal of this lab is to get familiar with the MARS simulator and
write a program in MIPS assembly language for playing musical scales.
Because this task can readily be accomplished
without any nested procedure calls (such as recursion), you won't need
to use the stack; that's what the next lab is for.

I expect you to do this lab in teams of two; please form your own team
of two. If you are having trouble finding a partner, see me.

For this lab project, your report can consist of just the code of your
final program. The assignment works up to that final program by way
of some simpler programs, but you don't need to include those,
assuming you get the final program to work. (On the other hand, if
you don't get the final program to work, you should include the latest
program that you did get to work as well as your further, non-working,
efforts.)

Be sure to write your program for human readability. That is, use
easily understood labels, leave blank lines between blocks of code,
and if the higher-level purpose served by a block of instructions is
not clear, include an explanatory comment.

Avoid excessive duplication of code. You may want to make use of a procedure (called with jal), for example.

If you include a procedure in your program, that procedure should follow the convention regarding what registers it must preserve. The code that calls the procedure should not rely on the values left in other registers.

You will do this lab on one of the computers in OHS 326, running Mac OS X. You will use
MARS as demonstrated in class. One way to run it would be to start by double clicking the Terminal application, which is the one that looks like this:
and then, in the Terminal window, type the following command:

open ~max/MCS-284/Mars.jar

Be sure that your program exits at the end by putting 10 in
register $v0 and then executing a syscall
instruction.

Data to include in your program

This defines two labels within the data segment of memory: chromaticPitches and cMajorPitches. Each of these labels corresponds with the starting address of a bunch of consecutive bytes of data, ending with a byte containing the value 0, which marks the end of the sequence of musical pitch codes. You will notice that both sequences run from 60 up to 72; in the MIDI code, this corresponds to middle C up to the next higher C. Looking more closely, you'll see that the chromatic pitches are consecutive integers. This is because a chromatic scale contains all the notes: the ones that correspond to a piano keyboard's black keys as well as the white ones. The C major scale, on the other hand, has pitches that sometimes go up by 2 rather than only 1. For example, at the very beginning it goes straight from 60 to 62. This is because it is including only the piano's white keys; in this particular case, it is going straight from C to D, skipping over C sharp (which is 61).

Program 1: playing an ascending scale

Your first program should begin by loading the starting address of one the scales into a register. (You are welcome to use whichever scale you prefer.) Then your program should execute a loop, each time loading a byte from the specified address, and so long as it is not the 0 marking the end, using system call number 33 to play the note, followed by incrementing the memory address and looping back for the next note. We will have demonstrated system call 33 in class, and it is also documented within MARS and on the web. You can pick whichever musical instrument code number you want, such as 58 for a brass sound or 112 for bells. (Debugging may be easier if each team uses a different instrument, so that you can tell whether sounds are coming from your program or another team's.) The duration and volume are matters of taste too; I find that 300 milliseconds and volume level 60 work well for me.

Program 2: playing ascending and descending scales

Once your program plays an ascending scale correctly, modify it so that it has a second loop that plays the same scale in the descending direction. The memory address where the first loop ended will indicate where the second loop should start. This loop can't use the same sort of end test as the first loop (based on loading a 0), because there is no guarantee that each list of pitches has a 0 before it. Instead, you will have to stop the loop either based on the address returning to the start or based on the number of loop iterations being the same as for the first loop.

Program 3: allowing the user to choose the scale

Once your program can play a scale ascending and then descending, it is time to add a user interface that allows the user to choose between the chromatic scale and the C major scale. Use system call 50 to ask the user whether they want the chromatic scale. If they press the "yes" button, play the chromatic scale in the ascending and descending directions as in your previous program. If they press "no," go through the same process, but with the C major scale. And if they press the "cancel" button, exit the program without playing any scales.