Quantcast
Channel: Programming Forums
Viewing all articles
Browse latest Browse all 51036

Hang trying to read hardware port

$
0
0
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:

#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?

Viewing all articles
Browse latest Browse all 51036

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>