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