1 #include "wakeup.h"
2 #include "boot.h"
3 
udelay(int loops)4 static void udelay(int loops)
5 {
6 	while (loops--)
7 		io_delay();	/* Approximately 1 us */
8 }
9 
beep(unsigned int hz)10 static void beep(unsigned int hz)
11 {
12 	u8 enable;
13 
14 	if (!hz) {
15 		enable = 0x00;		/* Turn off speaker */
16 	} else {
17 		u16 div = 1193181/hz;
18 
19 		outb(0xb6, 0x43);	/* Ctr 2, squarewave, load, binary */
20 		io_delay();
21 		outb(div, 0x42);	/* LSB of counter */
22 		io_delay();
23 		outb(div >> 8, 0x42);	/* MSB of counter */
24 		io_delay();
25 
26 		enable = 0x03;		/* Turn on speaker */
27 	}
28 	inb(0x61);		/* Dummy read of System Control Port B */
29 	io_delay();
30 	outb(enable, 0x61);	/* Enable timer 2 output to speaker */
31 	io_delay();
32 }
33 
34 #define DOT_HZ		880
35 #define DASH_HZ		587
36 #define US_PER_DOT	125000
37 
38 /* Okay, this is totally silly, but it's kind of fun. */
send_morse(const char * pattern)39 static void send_morse(const char *pattern)
40 {
41 	char s;
42 
43 	while ((s = *pattern++)) {
44 		switch (s) {
45 		case '.':
46 			beep(DOT_HZ);
47 			udelay(US_PER_DOT);
48 			beep(0);
49 			udelay(US_PER_DOT);
50 			break;
51 		case '-':
52 			beep(DASH_HZ);
53 			udelay(US_PER_DOT * 3);
54 			beep(0);
55 			udelay(US_PER_DOT);
56 			break;
57 		default:	/* Assume it's a space */
58 			udelay(US_PER_DOT * 3);
59 			break;
60 		}
61 	}
62 }
63 
main(void)64 void main(void)
65 {
66 	/* Kill machine if structures are wrong */
67 	if (wakeup_header.real_magic != 0x12345678)
68 		while (1);
69 
70 	if (wakeup_header.realmode_flags & 4)
71 		send_morse("...-");
72 
73 	if (wakeup_header.realmode_flags & 1)
74 		asm volatile("lcallw   $0xc000,$3");
75 
76 	if (wakeup_header.realmode_flags & 2) {
77 		/* Need to call BIOS */
78 		probe_cards(0);
79 		set_mode(wakeup_header.video_mode);
80 	}
81 }
82