in_beep.S 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*
  2. TODO not working on QEMU, but does produce some horrible sound on real hard.
  3. Maybe because I cannot get the beep working on my Ubuntu host?
  4. http://askubuntu.com/questions/19906/beep-in-shell-script-not-working
  5. It looks like the beep (port 0x61) just uses
  6. the PIT Channel 2 to generate the frequency, so understand the PIT first.
  7. Extracted from:
  8. https://github.com/torvalds/linux/blob/v4.2/arch/x86/realmode/rm/wakemain.c#L38
  9. The kernel has a Morse code encoder with it!
  10. Not using io_delay here, maybe would sound better with it?
  11. See also:
  12. - http://fly.srk.fer.hr/GDM/articles/sndmus/speaker1.html
  13. ## Port 0x61
  14. http://wiki.osdev.org/PC_Speaker
  15. Speaker specifics are there.
  16. The 0x4X IO are the PIT.
  17. */
  18. #include "common.h"
  19. BEGIN
  20. /* Chanel 2, square wave, load TODO?, binary */
  21. mov $0xb6, %al
  22. out %al, $0x43
  23. /* Set frequency of Channel 2. */
  24. .equ div, 1193181 / 1000
  25. mov div, %ax
  26. out %al, $0x42
  27. mov %ah, %al
  28. out %al, $0x42
  29. /* Dummy read of System Control Port B. TODO why? */
  30. in $0x61, %al
  31. /*
  32. Enable timer 2 output to speaker.
  33. THIS is where the sound begins.
  34. */
  35. mov $0x03, %al
  36. out %al, $0x61
  37. /* Loop forever to keep hearing it. */
  38. loop:
  39. nop
  40. jmp loop
  41. /*
  42. This is how a sound can be stopped.
  43. This code never runs in this example.
  44. */
  45. in $0x61, %al
  46. mov $0x00, %al
  47. out %al, $0x61