| 
									
										
										
										
											2008-04-10 23:28:10 +02:00
										 |  |  | #include "wakeup.h"
 | 
					
						
							|  |  |  | #include "boot.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void udelay(int loops) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	while (loops--) | 
					
						
							|  |  |  | 		io_delay();	/* Approximately 1 us */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void beep(unsigned int hz) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u8 enable; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!hz) { | 
					
						
							|  |  |  | 		enable = 0x00;		/* Turn off speaker */ | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		u16 div = 1193181/hz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		outb(0xb6, 0x43);	/* Ctr 2, squarewave, load, binary */ | 
					
						
							|  |  |  | 		io_delay(); | 
					
						
							|  |  |  | 		outb(div, 0x42);	/* LSB of counter */ | 
					
						
							|  |  |  | 		io_delay(); | 
					
						
							|  |  |  | 		outb(div >> 8, 0x42);	/* MSB of counter */ | 
					
						
							|  |  |  | 		io_delay(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		enable = 0x03;		/* Turn on speaker */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	inb(0x61);		/* Dummy read of System Control Port B */ | 
					
						
							|  |  |  | 	io_delay(); | 
					
						
							|  |  |  | 	outb(enable, 0x61);	/* Enable timer 2 output to speaker */ | 
					
						
							|  |  |  | 	io_delay(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define DOT_HZ		880
 | 
					
						
							|  |  |  | #define DASH_HZ		587
 | 
					
						
							|  |  |  | #define US_PER_DOT	125000
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Okay, this is totally silly, but it's kind of fun. */ | 
					
						
							|  |  |  | static void send_morse(const char *pattern) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char s; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while ((s = *pattern++)) { | 
					
						
							|  |  |  | 		switch (s) { | 
					
						
							|  |  |  | 		case '.': | 
					
						
							|  |  |  | 			beep(DOT_HZ); | 
					
						
							|  |  |  | 			udelay(US_PER_DOT); | 
					
						
							|  |  |  | 			beep(0); | 
					
						
							|  |  |  | 			udelay(US_PER_DOT); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case '-': | 
					
						
							|  |  |  | 			beep(DASH_HZ); | 
					
						
							|  |  |  | 			udelay(US_PER_DOT * 3); | 
					
						
							|  |  |  | 			beep(0); | 
					
						
							|  |  |  | 			udelay(US_PER_DOT); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		default:	/* Assume it's a space */ | 
					
						
							|  |  |  | 			udelay(US_PER_DOT * 3); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void main(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* Kill machine if structures are wrong */ | 
					
						
							|  |  |  | 	if (wakeup_header.real_magic != 0x12345678) | 
					
						
							| 
									
										
										
										
											2012-05-08 21:22:29 +03:00
										 |  |  | 		while (1) | 
					
						
							|  |  |  | 			; | 
					
						
							| 
									
										
										
										
											2008-04-10 23:28:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (wakeup_header.realmode_flags & 4) | 
					
						
							|  |  |  | 		send_morse("...-"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (wakeup_header.realmode_flags & 1) | 
					
						
							|  |  |  | 		asm volatile("lcallw   $0xc000,$3"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (wakeup_header.realmode_flags & 2) { | 
					
						
							|  |  |  | 		/* Need to call BIOS */ | 
					
						
							|  |  |  | 		probe_cards(0); | 
					
						
							|  |  |  | 		set_mode(wakeup_header.video_mode); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |