Page 1 of 1

SB 16 programming

Posted: Sun Nov 26, 2006 11:20 am
by pulsar
According to sb16 specs the dma channel can be 8 bit or 16 bit. bochs 2.2.6 wont let me set the 16 bit dma channel. It produces error and resets to default. It lets me set the 8 bit DMA channels. what are the known issues with bochs 2.2.6?

I can't make floppy reads. Dma seems to not work. I tried the same on VMware (with floppy) and it works.
[edit] Error in bochs because the kernel works in bochs 2.3 newly downloaded[/edit].

However it doesn't trigger sb16 interrupt. Here is a quick review of what i have done
1. IRQ is set to 10
2. DMA set to 1 (autoinitialized mode)
3. command to perform 8 bit autoinitialized transfer

Code: Select all

  if(output)
		out(0x220 + 0xC, 0x41);
	else
		out(0x220 + 0xC, 0x42);
	out(0x220 + 0xC, 0xAC);
	out(0x220 + 0xC, 0x44);
	
	if(output)
		out(0x220 + 0xC, 0xC0);
	else
		out(0x220 + 0xC, 0xC8);
	out(0x220 + 0xC, 0x20);
	out(0x220 + 0xC, 0xFF);
	out(0x220 + 0xC, 0x01);
I am trying to write to DSP but it is showing error as reading. DMA transfered 5 samples and it should have made an interrupt now, but not
SB16 log might help somebody to figure out my mistake.
00017135282 (4) DSP Data port write, value 41
00017135285 (4) DSP Data port write, value ac
00017135287 (4) DSP Data port write, value 44
00017135287 (4) DSP command 41 with 2 arg bytes
00017135291 (4) DSP Data port write, value c0
00017135294 (4) DSP Data port write, value 20
00017135296 (4) DSP Data port write, value ff
00017135298 (4) DSP Data port write, value 1
00017135298 (4) DSP command c0 with 3 arg bytes
00017135298 (4) DMA initialized. Cmd c0, mode 20, length 511, comp 0
00017135298 (5) DMA is 8b, 44100Hz, stereo, output, mode 1, unsigned, normal speed, 88200 bps, 6 usec/DMA
00017135310 (3) DMA reads not supported. Returning silence.
00017135574 (5) Sent 8-bit DMA 80, 1000 remaining
00017136774 (5) Sent 8-bit DMA 80, 900 remaining
00017137974 (5) Sent 8-bit DMA 80, 800 remaining
00017139174 (5) Sent 8-bit DMA 80, 700 remaining
00017140374 (5) Sent 8-bit DMA 80, 600 remaining

Posted: Tue Nov 28, 2006 4:42 am
by pulsar
Knock, knock
Somehow instead of writing i am performing reading. Pype i heard, you programmed SB card in assembly language sometime ago. Some of you might have information on this.
I am reading the SB documents again and again but i could not found the mistake.

[edit]
I just tried the single cycle transfer and interrupt doesn't occur. But if i set the DMA, it says "DMA is not supported and so returning silence" and interrupt occurs. Hey guys i heard a crack sound.
[/edit]

I am posting here the full source

Code: Select all

struct
{
Uint32 IoBase;
Uint32 phys;
void * virt;
Boolean done;
}SbInfo = {0x220,0,0 };

void DmaInit(unsigned channel, Uint32 address, size_t size, Boolean autoinit, Boolean read);

static Boolean SbPoke(Uint32 base, Uint8 val)
{
	unsigned temp,d=0;	
	for(temp = 0; temp < POKE_DLY; temp++)	{
		if((in(base + SBREG_WRITE) & 0x80) == 0)		{
			out( base + SBREG_WRITE, val);
			return true;
		}
	}
	return false;
}

void SbIsr(sContext *ctx)
{
Uint8 status=0;
memset(SbInfo.virt, 0xAA, PAGE_SIZE);
out( 0x220 + 4, 0x82);	//select interrupt flag
status = in(0x220 + 5);
if(status & 0x01)			//  interrupt from 8 bit DMA
	in(0x220 + 0x0E);	// Acknowledge interrupt
else if(status & 0x02)		// interrupt from 16 bit DMA
	in(0x220 + 0x0F);	// Acknowledge the interrupt
}

Boolean SbDetect(Uint32 base)
{
	int i = 0;	
	out( base + SBREG_RESET, 0x01);
	out( base + SBREG_RESET, 0x00);	
	for( i =0; i< 10; i++){
		if(in(base + SBREG_POLL) & 0x80)
			break;
	}
	if (i == 10)
		return false;

	for( i =0; i< 10; i++)	{
		if(in(base + SBREG_READ) == 0xAA)
			break;
	}
	if (i == 10)
		return false;	
	SbPoke(base, SBCMD_VERSION);	
	print("\nDSP version : %d",in( base + SBREG_READ));
	print(".%d",in(base + SBREG_READ));	
	return true;
}

void SbStartIo(Uint8 channel, Boolean output)
{
	out(0x220 + 0xC, 0xD1);	
	out(0x220 + 4, 0x81);
	out(0x220 + 5, 1 << channel);
	DmaInit( channel, SbInfo.phys, 0x1000, true, false);	
	if(output)
		out(0x220 + 0xC, 0x41);
	else
		out(0x220 + 0xC, 0x42);
	out(0x220 + 0xC, 0xAC);
	out(0x220 + 0xC, 0x44);	
	if(output)
		out(0x220 + 0xC, 0xC6);
	else
		out(0x220 + 0xC, 0xCE);
	out(0x220 + 0xC, 0x00);			/* 8 bit mono unsigned PCM */
	out(0x220 + 0xC, 0xFF);
	out(0x220 + 0xC, 0x2);
}


void SbInit(void) 
{
print("\nSound Blaster Probing started...");
if(SbDetect(0x220))
{
	i386RegisterIrq( 10, SbIsr);
	out(0x220 + 4, 0x80);
	out(0x220 + 5, 1 << 3);
	SbInfo.phys = MemAllocLow();
	SbInfo.virt = VmmAlloc(1, 1, false);
	MemMapRange( SbInfo.virt, SbInfo.phys, SbInfo.virt + PAGE_SIZE, PRIV_WR | PRIV_KERN | PRIV_PRES);
	memset(SbInfo.virt, 0xAA, PAGE_SIZE);
	SbStartIo(3, true);
}
}

Posted: Sat Dec 02, 2006 7:39 am
by pulsar
May be i thought this will be useul to someone. I managed to produce sound in bochs.
I am attaching the source