PSG trouble

For anything related to sound (YM2612, PSG, Z80, PCM...)

Moderator: BigEvilCorporation

Post Reply
M-374 LX
Very interested
Posts: 61
Joined: Mon Aug 11, 2008 10:15 pm
Contact:

PSG trouble

Post by M-374 LX » Sat Mar 31, 2012 3:41 am

With the help of this page, I attempted to write a C function to generate a tone by the PSG. However, I got no sound.

Code: Select all

void play_tone()
{
	register ulong *p;
	
	p = (ulong *)0xC00011;
	
	/* 440Hz for channel 0 */
	*p = 0x8E;
	*p = 0xF;
	
	*p = 0x90; /* Maximum volume for channel 0*/
	*p = 0xBF; /* Silence on channel 1*/
	*p = 0xDF; /* Silence on channel 2*/
	*p = 0xFF; /* Silence on channel 3*/
}
What is wrong?

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: PSG trouble

Post by Stef » Sat Mar 31, 2012 9:06 am

M-374 LX wrote:With the help of this page, I attempted to write a C function to generate a tone by the PSG. However, I got no sound.

Code: Select all

void play_tone()
{
	register ulong *p;
	
	p = (ulong *)0xC00011;
	
	/* 440Hz for channel 0 */
	*p = 0x8E;
	*p = 0xF;
	
	*p = 0x90; /* Maximum volume for channel 0*/
	*p = 0xBF; /* Silence on channel 1*/
	*p = 0xDF; /* Silence on channel 2*/
	*p = 0xFF; /* Silence on channel 3*/
}
What is wrong?
You should start by declaring p like that :

Code: Select all

volatile unsigned char *p;
	
p = (unsigned char *)0xC00011;

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sat Mar 31, 2012 5:10 pm

Just a little more info on WHY...

You declared p to be a pointer to ulong data. A ulong is 4 bytes, and since the 68000 is big-endian, the data you store through the pointer will end up at p+3 for the LSB. So even if you could use long accesses to the device, the data is going to the wrong address. In fact, you are trying to store a ulong to an odd address, which will instantly fault on the 68000.

Stef's change is to make p a pointer to an unsigned char, or 1 byte. That way you are doing byte accesses to the proper address. Now notice how it also uses volatile - that prevents the compiler from doing things like leaving the data in a temp variable instead of reading/writing the data when you tell it to. The data will always be read from memory or written to memory when you use the accessor function on the pointer without regard to if you have done so before.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Sat Mar 31, 2012 5:38 pm

Thanks for explaining Chilly ;) I admit that give solution without explaining is not very helpful somewhat :p

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sat Mar 31, 2012 8:20 pm

Stef wrote:Thanks for explaining Chilly ;) I admit that give solution without explaining is not very helpful somewhat :p
Well, not all of us NEED the why, just need the error pointed out and we go "D'OH!!" :lol:

But that's one of the nice things about forums - if the guy answering forgets something, someone else can chime in with a bit more info.

Post Reply