82 lines
		
	
	
	
		
			1.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			82 lines
		
	
	
	
		
			1.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#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)
							 | 
						||
| 
								 | 
							
										while (1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |