CS-220, Lab # 7
Due Date: 4-20-06

In this lab you are to write a .COM-file-format assembly language program 
and a C language program for an IBM PC-compatible computer, each of which 
will receive keyboard characters entered by the user, and, if the key 
pressed corresponds to one of the key-of-c piano keys (namely A, B, C, D, 
E, F, G, a, b, c, d, e, f, g), output a tone with the frequency of that 
musical note. Here upper case letters represent lower pitch tones and lower 
case letters the higher pitch tones (an octive above). The following table 
gives the frequencies of some keys on a piano keyboard:

Note        Frequency (Hz)        Note               Frequency (Hz)
   Middle-C       262                C-sharp (D-flat)      277
   D              294                D-sharp (E-flat)      311
   E              330
   F              349                F-sharp (G-flat)      370
   G              392                G-sharp (A-flat)      415
   A              440                A-sharp (B-flat)      466
   B              494
   high-c         523                c-sharp (d-flat)      554
   d              587                d-sharp (e-flat)      622
   e              659
   f              698                f-sharp (g-flat)      740
   g              784                g-sharp (a-flat)      831
   a              880                a-sharp (b-flat)      932
   b              988

You are not required to implement sharps and flats, but may do so if you wish.
In that case you will need to use different keys to represent these notes.
Perhaps you could use the numeric keys for that.

Your program should continue "playing" notes until some special non-note key
(perhaps the 'Q' key, for Quit) is pressed.

Sound on a PC:

As discussed in class, on an IBM PC, port 61h controls, among other things, 
the speaker. Although there is more than one way to produce a tone using this 
port, in this lab you will use the fact that channel 2 of the PC's Intel 8254 
timer chip can be made to send a square wave of a specified frequency to the 
speaker. The steps outlined in the notes at: 
http://www.cs.binghamton.edu/~reckert/220/8254_timer.html should be followed. 

1. Program timer channel 2 of the 8254 for square wave output and binary
count operation by sending the appropriate bit pattern to output port 43h. 
This only needs to be done once.

Command register format:

value:        1   0   1   1   0   1   1   0

           |  7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  |
              |   |   |   |   |   |   |   |__ Count format (0=binary)
              |   |   |   |   |___|___|_______ Mode of operation 
              |   |   |   |                    (3=square wave)
              |   |   |__ |_______ How to access latch (3=LSB then MSB)
              |___|_______________ Timer/oscillator channel

2. Determine the timer count that corresponds to the desired tone frequency:  
count = 1193180/frequency. (The frequency, of course, depends upon which key 
was pressed.)

3. Send the count computed in the previous step to output port 42h. This is
done in two steps: First output the least significant byte of the count to
port 42h; then output the most significant byte of the count to port 42h.

4. Turn on timer 2 (thus starting the tone) by sending xxxxxx11b to port
61h. Here the bits marked with x should not be changed, as they control
other things on the PC.

5. Delay for a short period of time. (Perhaps 1/4 second; the exact value is
not important as long as it's not so short that the user can't hear the sound
or so long that keyboard operation becomes sluggish. Hint: because of the
high speed of the PC system clock, you will probably need a nested delay loop.)

6. Turn off timer 2 (thus terminating the sound) by sending xxxxxx10b to
port 61h. Again the bits marked with x should not be changed.

In order to get the notes, your assembly language program should use the DOS 
single-character input service of int 21h to get the ASCII code of the key. If 
the key is one of the notes of the piano keyboard, the program should generate 
a tone of the corresponding frequency as described above. If not, it should not 
produce a tone.

As mentioned above, the assembly language program should be written as a .COM 
file executable. The reason is that in the next lab you will modify the program 
to make it into an interrupt service routine that intercepts the keyboard 
interrupt. This is much easier to do if the program has a single segment. We 
will be talking about interrupts in class very soon.

In order to do port-mapped I/O in assembly language you will need to use the 
IN and OUT instructions. To do it in C, use the inportb() and outportb() 
functions described in class. Also in the C version be sure to put the 
following two #include statements at the beginning of your program:

#include <conio.h>
#include <dpmi.h>

You should demonstrate your programs to the lab instructor. If you cannot do
that, you must submit a diskette or CD-ROM containing the source and executable 
files for each.

You should submit the standard documentation--i.e., a readable, well-
documented .LST file. Flow charts and a hierarchy chart are not required.