Sunday, 20 October 2013

beep! beep! (in grub4dos)

I had a request today from a blind person who wanted the grub4dos menu to beep when it loaded so that he would know when the countdown timer had begun. He was following my 'Tutorial 89 - Automated Windows partition backup\restore boot menu using CloneZilla' and wanted to be able to hit F4 and automatically restore his system.

Unfortunately not all hardware is fitted with a small internal speaker or internal 'beeper'. Most PCs are however - this is the thing that you may hear beep when you switch on your PC or it may beep several times if you have dislodged the DIMM memory cards!

Assuming that your PC does have an internal beeper, we can make it beep by sending a Ctrl-G character to the 'console'.

In grub4dos, we can use the internal function Fn.2 to send Ctrl-G to the 'display' as follows:

call Fn.2 7

This will work if you place it at the top of your menu before any graphicsmode or splashimage calls are made, because the display must be in low-res text mode (CGA) for this to work. So if you want to try this make sure you type graphicsmode 3 first if you are already in hi-res mode after loading a hi-res background bitmap! Of course, as this is a hardware 'beep', it won't work in an emulator or VM either.

We can flash the screen white and beep 3 times using the code below, as long as it is at the start of our menu.lst file (all one line).

color standard 0xF1 && clear && call Fn.2 7 && call Fn.2 7 && call Fn.2 7 && pause --wait=3 > nul && color standard 0xf && clear

If you don't want to see a flashing cursor use:
call Fn.5 0 128 
after the first 'clear' command, this sends the cursor off the screen to row 128! It will also mean that if the calls to Fn.2 produces any odd characters, they won't be seen.

However, once we have switched to a hi-res graphics mode, this trick of sending Ctrl-G to the 'display' will no longer work. Instead we will have to call the BIOS directly to output Ctrl-G to the console.

We can do this using the nice little grub4dos executable 'bios' from Chenall (download the bios.zip from here).

To make 3 beeps, each one second apart in any resolution screen mode, we can use this (assuming the bios executable is in the root of the drive):

/bios int=0x10 eax=0xe07 ebx=0x0 > nul
pause --wait=1 > nul
/bios int=0x10 eax=0xe07 ebx=0x0 > nul
pause --wait=1 > nul
/bios int=0x10 eax=0xe07 ebx=0x0 > nul

Most notebooks and many 'All-in-One' PCs are not fitted with an internal speaker though, so we can't make an annoying noise on every system that we boot from...