/* Copyright (C) Magna Carta Software, Inc. 1987-1991. All Rights Reserved. SOUND -- Program the 8253 to produce sound independently of the CPU Note: This procedure uses the BIOS time-of-day count to control the duration and so is only accurate to approximately 55 milliseconds. */ #define CWT_DEVELOPMENT #if (defined(CCTW) || defined(_WINDOWS)) #include #endif #include #include #if (defined(MSC) || defined(__WATCOMC__) || defined(__HIGHC__)) #include #endif #define CLOCK_RATE 1193182L #define CLOCKS_PER_SECOND 18.206481934 #define PORTB 0X61 #define CMD8253 0X43 #define CH0_8253 0X40 #define CH2_8253 0X42 #define LOW_TIME 0X46C #define HIGH_TIME 0X46E void set_sound_off(void); short set_sound_on(unsigned short pitch, unsigned short duration) { union REGS regs; unsigned short s_count, count; /* CONFIRM VALID PITCH */ if (pitch <= 0) return (-1); pitch = (unsigned) (CLOCK_RATE/pitch); /* CONVERT DURATION TO CLOCK TICKS */ if (duration) duration = (unsigned short) (duration*18206L/1000000L); outp(PORTB, inp(PORTB) | 3); /* send byte to port b */ outp(CMD8253, 0XB6); /* set up I/O register (10110110) */ outp(CH2_8253, pitch & 0XFF); /* send counter to latch */ outp(CH2_8253, pitch >> 8); /* IF SPECIFIC TIME INTERVAL NOT REQUESTED (i.e. continuous sound) */ if (duration) { setwordreg(ax) = 0; /* get time service */ int86(0X1A, ®s, ®s); s_count = setwordreg(dx); /* low part of timer count */ do { setwordreg(ax) = 0; /* get time service */ int86(0X1A, ®s, ®s); count = setwordreg(dx); /* low part of timer count */ } while (count < duration+s_count); } if (duration) set_sound_off(); return (0); } void set_sound_off(void) { /* TURN OFF THE SOUND (CLEAR LOW 2 BITS) */ outp(PORTB, inp(PORTB) & 0XFC); /* RESTORE ORIGINAL COUNTER VALUE */ outp(CMD8253, 0XB6); /* set up I/O register (10110110) */ outp(CH2_8253, 0); /* send counter to latch */ outp(CH2_8253, 0); } void key_click(void) { set_sound_on(10, 55); }