Jump to content

Adding Boot sound (sub part of How to boost the OS X boot process)


GrootWitBaas
 Share

47 posts in this topic

Recommended Posts

So the basic thing here is, This is a sub part of the How to boost the OS X boot

 

So the basics, the PC speaker can be accessed using asm code writing to Timer 2, see here

Also it can be assessed from c++ using a simple printf("\a"); this will only send a system beep.

When using asm it is actually possible to create a specific tone or if send in sequence a "song"

 

So we all run OS X on our hack, but we don't have a apple sosume.aiff when powered up. this is what I want to fix here.

 

There is already some posts made about it, and I will just link them here for reference. I will come back later and edit here to have every thing in one place.

 

post one

and there is more down there

 

O sound is easy in dos and windows asm, but the goal here is to have everything done natively in osx using direct asm or asm via c++.

 

More to follow

Link to comment
Share on other sites

Hi GWB,

This is really exciting, an opportunity to both make a really cool contribution to the scene as well as learning new stuff.

 

Currently spending time reading up on how to actually do programming with asm in gcc (and C++ !!) and understand the key principles. eg: Just managed to get my head around some of the principles in the file cpu/proc_reg.h, that DHP pointed us to, such as why it uses %% and what all those : : : things are for! Make my head spin when I first looked at it :thumbsup_anim:

 

If an experienced asm programmer chimes in, no doubt we'll get there faster with less headaches. Although there's nothing like making your own errors and sort of re-inventing the wheel, as an aid to the learning process!

Link to comment
Share on other sites

Ok just to give every one What I have come up so far, simple c++ file. Currently It gives me a Segmentation fault basicly telling me I don't have the right to address the register. Not sure if it is only on this PC or the same for all, so feel free to try it out.

 

#include <stdio.h> //(not sure about this, but looks like it is needed to getchar)

int main() 
{
// AT&T source, destination
//Turn sound on	
asm volatile   ("movb $0xB6, %al;" //{prepare timer to start generating sound }
			"outb %al, $0x43;"
			"movw $0x254, %ax;" //{0x254 is 2000hz (I think) }
			"outw %ax, $0x42;" //{send low byte to port 42h }
			"movb %al, %ah;"
			"outb %al, $0x42;" //{send high byte to port 42h }
			"inb $0x61, %al;" //{get current value of port 61h }
			"or %al, 0x3;" //{set lowest two bits of 61h "on" -- activate speaker }
			"outb  %al, $0x61;" //{rewrite to port 61h }"
			); 
printf("on \nSleep 3\n");
getchar(); //wait for Key just to add a delay, I don't know what needs to be included for sleep(x) to work
//Turn sound off
asm	volatile	("inb $0x61, %al;" //{ get value of 61h }
			 "and %al, 0xFC;" //{ set lowest two bits of 61h "off" -- deactive speaker }
			 "outb  %al, $0x61;"//{ rewrite to port 61h }"
			 );   
}

 

I have saved it as beep.c and used g++ beep.c -o beep to compile, chmod a+x beep to make it executable and ./beep to run.

As I said it does not work right now, but in theory should work.

beep_c.txt

Link to comment
Share on other sites

This is a very interesting and crazy project!

 

Your goal is really to have the PC speaker play the Apple boot chime?

 

On my Hack, when I start Windows XP in Parallels, my PC speaker beeps exactly like it does when I turn on my PC. It's funny that they left that code in on the Mac version of Parallels. I still can't get used to it, it's strange hearing that sound coming from the PC case in the middle of normal every day use.

 

Just to let you know that it is possible to make the PC speaker do something even in OS X.

 

There are lots of interesting hits w/ code examples if you google "PC speaker sample playback". Maybe you can use some of that. It's all ~20 years dusty old code though. :thumbsup_anim:

 

Good luck.

Link to comment
Share on other sites

Yes Most code related to pc speaker is from when I was young and Turbo Pascal was the best. :tomato:

Most ideas start off as crazy ;)

 

Actually when the kernel is booted and your sound drivers are loaded, it seems there is no more support for the PC Beep(gets directed to sound-card), only before sound drivers are loaded can I have the pc beep. this is done in the early stage of boot, round about where your boot-loader brings up the selections for your os.(depending on your boot-loader)

A normal printf("\a"); can pruduce this standard pc beep, but so far I can only get this in early boot.

 

Interesting you say Parallels can do this beep, I'll have a look.

Link to comment
Share on other sites

I remember reading something about the Parallels BEEP so I looked it up for you. Here it is:

 

Source: P5K PRO thread.

DHP thanks again you give me more to read and follow on ...pitty that in that post is said "The following devices have been removed with this update: ....Device SPKR (Speaker)"

 

Yeah that was me, I changed my name ;) .

then maybe you can shed more light on Device SPKR(Speaker) ? I am still doing the google on speaker.h and so on, but at this time it becomes very hard to separate scrap from useful .....this will not be easy, I have a 200+ line c file already ....still not compiling ....but working on it

Link to comment
Share on other sites

erm yes ... any one have this SPKR section from a DSDT handy ...I know google, I have 25 google tabs open right now

 

We meet again!

 

Here it is:

Device (SPKR)
               {
                   Name (_HID, EisaId ("PNP0800"))
                   Name (_CRS, ResourceTemplate ()
                   {
                       IO (Decode16,
                           0x0061,             // Range Minimum
                           0x0061,             // Range Maximum
                           0x00,               // Alignment
                           0x01,               // Length
                           )
                   })
               }

Link to comment
Share on other sites

AppleHDA checks MaximumBootBeepValue which controls the volume level of the boot chime, but I don't have this property in my hack's ioreg dump. I wonder if adding it helps.

 

I'm pretty confident that AppleHDA loads a data block from memory (firmware) and calls some routine to produce the boot chime sound.

Link to comment
Share on other sites

MaximumBootBeepValue seems to be more related to the sound card, not internal speaker. This is only initiated once the kext for it is loaded. not sure when this happens, but I believe it is later in the boot process. It still could be a good idea to have it in ....but I think that's a whole new ball game.

If AppleHDA does load a block, we need to pass this info to it ....erm ok I will have a look, but again this is not my field.

then again if this is the case, how come the boing is there even with a blank disk (ie no AppleHDA)

 

I do have a SPKR in my ioreg, see below. The problem seems that I am not able to access it from asm code ...using in-line asm. I have however with al the info given here to me, plus 30+ pages from google, a basis that I think might work. I need to learn more c++ thou before it will (I am no programmer and only on week 2 of Sams Teach yourself c++ in 21 days)

post-288399-1298140629_thumb.png

Link to comment
Share on other sites

Got the beep going. Horrid coding, coz I've no idea what I'm doing!!

 

Added two files to boot2:

speaker.h

static inline void enable_spkr(void)
// Turn on speaker
{
__asm__ volatile(" inb   $0x61,%%al	  \n\t"	/*get port 61h*/
				 " orb   $0x3,%%al	  \n\t"	/*			*/
				 " outb  %%al,$0x61	  \n\t"	/*write port 61h*/
				 : : : "%al"					/*no outs:no ins:clobber al*/
				 );
}

//==============================================================================
static inline void disable_spkr(void)
// Turn off speaker
{	
__asm__ volatile(" inb   $0x61,%%al	  \n\t"	/*get port 61h*/
				 " and   $0xFC,%%al	  \n\t"	/*				*/
				 " outb  %%al,$0x61	  \n\t"	/*write port 61h*/
				 : : : "%al" 					/*no outs:no ins:clobber al*/
				 );
}

//==============================================================================
static inline void maketone(void)
// Make a tone to output via speaker
{
__asm__ volatile("movb 0x4b, %%al		\n\t"	/* prepare timer to start generating sound */
				 "outb %%al, $0x43		\n\t"	/* send to timer */
				 "movw $0x4a9, %%ax		\n\t"	/* TONEOUT = word: 1193180 / frequency  1khz use 0x4A9 */
				 "outw %%ax, $0x42		\n\t"	/*send low byte to port 42h */
				 "movb %%al, %%ah		\n\t"
				 "outb %%al, $0x42		\n\t"	/* send high byte to port 42h */
				 :	:	
				 );
}
//==============================================================================

 

speaker.c

#include "boot.h"
#include "speaker.h"

extern void makebeep(void)
{
maketone();
enable_spkr();
sleep (1);
disable_spkr();
}

 

ALSO:

added this in boot.c near the top

#include "speaker.c"

 

added this in boot.c after showBootLogo()

 

line 212: makebeep();

 

Sounds nasty (perhaps am using bad frequency number), but as proof of concept...

 

Now we just have to figure the reading / sending as PCM of WAV file (as well as making decent code!)

Link to comment
Share on other sites

Nice work everyone ...

getting the tune is not that hard ....but I need to just have a look at all this ...information overload ....

again great work

 

Got the beep going. Horrid coding, coz I've no idea what I'm doing!!

Added two files to boot2:

speaker.c

ALSO:

added this in boot.c near the top

#include "speaker.c"

added this in boot.c after showBootLogo()

line 212: makebeep();

Sounds nasty (perhaps am using bad frequency number), but as proof of concept...

Now we just have to figure the reading / sending as PCM of WAV file (as well as making decent code!)

That works Perfect ..... OK let me work on the FX for the sound ....This I am sure can be done.

Link to comment
Share on other sites

Based on the code above, I have made 1 or 2 small changes. this creates a 2 tone at boot. You had the %%al to %%ah the wrong way around from what I see. Still not sure what to use for type word, so I duplicated the maketone routine to make two notes. attached is the two files. try it and let me know. also I need something else than sleep for a delay, I need milliseconds, not seconds ...I'm sure this is possible

speaker_c.txt

speaker_h.txt(updated)

 

Also I load this sooner in boot.c, right here, just in case verbose mode it will still sound (it is for me line 201)

	initPlatform(biosdev);	// Passing on the boot drive.
makebeep();

Groot

Link to comment
Share on other sites

A Quick update, attached is the 2 files cleaned up a bit, and more playinf a tune of sorts, feel free to test. also attached is a some Turbo Pascal code for playing a wav to pc speaker ...I am working on "transcribing" this, but am not that good yet in c++ (but used to be good in TP LOOOOOOOOng time ago ....)

Also attached is the sosume file in wav (mono)

 

Have fun

 

speaker_c.txtspeaker_h.txtWAV_PAS.txtsosume.wav

 

Remember both speaker files goes in boot2 and you have to add the one line in boot.c to call it.

 

Ok some more on the PAS file.

Basicly the check the file header, then read the length of data into a array of bits

next they pas the bits to the speaker so looks like no conversion.

I don't know how to read a file in binary into c++ so this is where I need to google/read allot to get it done, or help from you.

Passing the bits I can do no problem.

Link to comment
Share on other sites

Based on the code above, I have made 1 or 2 small changes. this creates a 2 tone at boot. You had the %%al to %%ah the wrong way around from what I see. Still not sure what to use for type word, so I duplicated the maketone routine to make two notes. attached is the two files. try it and let me know. also I need something else than sleep for a delay, I need milliseconds, not seconds ...I'm sure this is possible

speaker_c.txt

speaker_h.txt(updated)

 

Also I load this sooner in boot.c, right here, just in case verbose mode it will still sound (it is for me line 201)

	initPlatform(biosdev);	// Passing on the boot drive.
makebeep();

Groot

 

Have tested and all works well. Great work so far! I've been trawling the web about wav and C++ will let you know if I come across anything promising

Link to comment
Share on other sites

AppleHDA checks MaximumBootBeepValue which controls the volume level of the boot chime, but I don't have this property in my hack's ioreg dump. I wonder if adding it helps.

 

I'm pretty confident that AppleHDA loads a data block from memory (firmware) and calls some routine to produce the boot chime sound.

 

I think that it is saved in pram.

Try this:

set your volume to 0 and reboot. You will have no beep at boot.

Now reboot but before loading again the system erase the pram

You will come back with the beep volume at default level...

Link to comment
Share on other sites

...e Turbo Pascal code for playing a wav to pc speaker ...I am working on "transcribing" this, but am not that good yet in c++..

Me neither. LOL.

Actually that pascal prog, transcribed, would be brilliant & nice as could be used to play any normal WAV file.

However I was thinking of just doing a very basic approach w/o all the checks, just set up the speaker port and fire out the PCM data taken from a "stripped down WAV data-only" binary file of the boot chime edited in hex programmer. That is under our control, and saves having to read in, check the WAV file, configure to match sample rate etc.

Well, mostly it seemed easier on the programming side of things to have a "special" hacked binary file holding the raw data; but is not a universal solution.

(So spent this morning reading up on WAV and AIFF file formats).

Link to comment
Share on other sites

 Share

×
×
  • Create New...