SB 16 programming

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
pulsar
Member
Member
Posts: 49
Joined: Wed Nov 22, 2006 1:01 am
Location: chennai

SB 16 programming

Post 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
User avatar
pulsar
Member
Member
Posts: 49
Joined: Wed Nov 22, 2006 1:01 am
Location: chennai

Post 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);
}
}
User avatar
pulsar
Member
Member
Posts: 49
Joined: Wed Nov 22, 2006 1:01 am
Location: chennai

Post by pulsar »

May be i thought this will be useul to someone. I managed to produce sound in bochs.
I am attaching the source
Attachments
sb.c
(7.23 KiB) Downloaded 126 times
everyone here are best programmers ( not yet not yet)
Post Reply