Beep_userspace.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <sys/mman.h>
  6. #include <stdint.h>
  7. #include <sys/io.h>
  8. #include <string.h>
  9. #include <sys/ioctl.h>
  10. #include <errno.h>
  11. typedef unsigned char UINT8;
  12. typedef unsigned short UINT16;
  13. #define note(x) ((119318200+(x)/2)/(x))
  14. void printfHelp(char *argv0)
  15. {
  16. printf("Ver: 20221223\n\n");
  17. printf("<%s> <times>\n", argv0);
  18. printf("For Example:\n");
  19. printf("%s 4 \n", argv0);
  20. printf("\n%s -h:for help! \n", argv0);
  21. }
  22. UINT8 IoRead8 (UINT16 addr)
  23. {
  24. return inb(addr);
  25. }
  26. void IoWrite8 (UINT16 addr, UINT8 data)
  27. {
  28. outb(data,addr);
  29. }
  30. void DelayMs(int ms)
  31. {
  32. unsigned int i = 0, n = 656.36*ms;
  33. for (i = 0; i < n; i++)
  34. IoRead8(0x0b);
  35. }
  36. void BeepOn(UINT8 note, UINT8 octave)
  37. {
  38. // beep tones
  39. UINT16 tones[8] = { note(26163),note(29366),note(32963),note(34923),note(39200),note(44000),note(49388),note(26163 * 2) };
  40. UINT16 Frequency = tones[(note % 8)];
  41. if (octave - 1 >= 0)
  42. Frequency >>= octave - 1;
  43. else
  44. Frequency <<= 1 - octave;
  45. //set up channel 1 (used for delays)
  46. IoWrite8(0x43, 0x54);
  47. IoWrite8(0x41, 0x12);
  48. //set up channel 2 (used by speaker)
  49. IoWrite8(0x43, 0xb6);
  50. IoWrite8(0x42, (UINT8)Frequency);
  51. IoWrite8(0x42, (UINT8)(Frequency >> 8));
  52. //turn the speaker on
  53. IoWrite8(0x61, IoRead8(0x61) | 3);
  54. }
  55. void BeepOff(void)
  56. {
  57. IoWrite8(0x61, IoRead8(0x61) & 0xfc);
  58. }
  59. void Beep(UINT8 note, UINT8 octave, unsigned int duration)
  60. {
  61. BeepOn(note, octave);
  62. DelayMs(duration);
  63. BeepOff();
  64. }
  65. int main(int argc, char* argv[])
  66. {
  67. int i = 0;
  68. UINT8 mytimes;
  69. if (argv[1] == NULL || !strcmp(argv[1], "-h"))
  70. {
  71. printfHelp(argv[0]);
  72. return 0;
  73. }
  74. if (iopl(3) == -1) {
  75. fprintf(stderr, "Failed to set IOPL: %s\nRun with sudo!\n", strerror(errno));
  76. return EXIT_FAILURE;
  77. }
  78. mytimes = (UINT8)strtoul(argv[1], NULL, 10);
  79. for (i = 0; i < mytimes; i++)
  80. {
  81. Beep(6, 1, 120);
  82. DelayMs(120);
  83. }
  84. }