Hello all.
Over the weekend I got bored and wanted something fun to toy with. Well, I have an old 486 laptop, a copy of Turbo C and nerves of steel. I wanted to learn how to make sounds and project them out the PC speaker.
After some research and experimentation, I was able to write a program that sets the countdown period of timer 2 and connects it to the PC speaker to produce sound:
And...it works! Just not on the laptop. It hangs at line 39 where it tries to read port 61h and gets no further. Meanwhile if I run the same binary in DOSBox it happily skips up the D major scale like its supposed to.
Maybe I'm missing something simple. Messing with hardware even on a simple level like this is a bit new to me so its possible. I guess I'm just looking for a nudge in the right direction.
Thoughts?
Over the weekend I got bored and wanted something fun to toy with. Well, I have an old 486 laptop, a copy of Turbo C and nerves of steel. I wanted to learn how to make sounds and project them out the PC speaker.
After some research and experimentation, I was able to write a program that sets the countdown period of timer 2 and connects it to the PC speaker to produce sound:
#include <stdio.h>
#include <conio.h>
int main(void)
{
/* Declare PIT variables. */
int freqs[] = { 294, 330, 367, 392, 440, 494, 554, 587 };
int countdown = 1193180 / 294;
int lowerbyte = countdown & 0xff;
int higherbyte = (countdown >> 8) & 0xff;
int connected = 0;
int x = 0;
unsigned int value = 0;
int period = 500;
/* Here we go... */
printf("Making beep sounds...\n\n");
getchar();
while ( x < 8 )
{
/* Adjust the countdown for the new frequency. */
countdown = 1193180 / freqs[x];
lowerbyte = countdown & 0xff;
higherbyte = ( countdown >> 8 ) & 0xff;
/* Set the timer. */
printf( "Setting new frequency of %d Hz.\n", freqs[x] );
outportb( 0x43, 0x6b );
outportb( 0x42, lowerbyte );
outportb( 0x42, higherbyte );
/* Connect to the speaker, if not already connected. */
if ( connected == 0 )
{
printf( "Connecting to the speaker.\n" );
getchar();
printf( "Connecting...\n" );
/* Get the value of the port. Set bits 0 and 1 of the control byte. */
value = inportb( 0x61 );
printf( "Value of the speaker port is %d. Adjust mode for timer connection.\n", value );
value = value | 3;
printf( "Value is now %d. Setting the control byte.\n", value);
getchar();
/* Connect to speaker. */
outportb( 0x61, value );
printf( "Connected.\n" );
connected++;
}
/* Sleep a while. */
printf( "Sleeping... " );
delay(period);
printf( "done.\n" );
x++;
}
/* Disconnect the speaker from the timer and reset the port. */
printf( "Disconnecting the speaker... " );
value = inportb( 0x61 );
value = value & 0xfc;
outportb( 0x61, value );
printf( "done.\n" );
/* Declare we are done. */
printf( "Sound test done.\n" );
return 0;
}
And...it works! Just not on the laptop. It hangs at line 39 where it tries to read port 61h and gets no further. Meanwhile if I run the same binary in DOSBox it happily skips up the D major scale like its supposed to.
Maybe I'm missing something simple. Messing with hardware even on a simple level like this is a bit new to me so its possible. I guess I'm just looking for a nudge in the right direction.
Thoughts?