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 emailing me the code of your final program. (Be sure to include both partners' names.) 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 OS X. You will use
MARS as demonstrated in class.
You can click on the Mars icon in the Applications folder; it looks like this:
Be sure that your program exits at the end by putting 10 in
register $v0
and then executing a syscall
instruction.
Your program should include the following lines:
.data chromaticPitches: .byte 60,61,62,63,64,65,66,67,68,69,70,71,72,0 cMajorPitches: .byte 60,62,64,65,67,69,71,72,0 .text
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).
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 you use a different instrument than your neighbors do, so that you can tell whether sounds are coming from your program or one of the others.) If you want a list of all the instruments, look at the General MIDI Level 1 Instrument Patch Map. However, you need to subtract 1 from the number given in the "PC#" column of that table. (For example, you'll notice they've listed "tinkle bell" as 113, which corresponds to the 112 mentioned previously.)
The duration and volume are matters of taste too; I find that 300 milliseconds and volume level 60 work well for me.
Make sure your program does not play the 0 at the end of the scale; it is just an end marker, not a tone to play.
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.
Your program should not play the 0 between the ascending and descending scales.
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.