FDC prints junk?

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
AUsername
Member
Member
Posts: 54
Joined: Sun Feb 01, 2009 9:07 pm

FDC prints junk?

Post by AUsername »

Well my FDC driver fails for some reason. It loads the sector using the DMA but when I go to print out the data returned it's jumbled up parts of the sector. It appears to skip entire parts of the sector at random for no reason.

So I rewrote it from scratch (both the DMA "driver" and the FDC driver) and the same exact thing happens, same junk. It's just faster. (which is irrelevant)

Honestly I'm at a dead end. I've looked over the code many times and I don't see anything wrong. I would assume it's with the DMA but it looks fine to me.

DMA:

Code: Select all

void dma_mask_channel(uint8_t channel){
	if (channel<=4){
		outportb(0x0a,(1 << (channel-1)));
	}else{
		outportb(0xd4,(1 << (channel-5)));
	}
}

void dma_unmask(uint8_t channel){//Chan2=0x6
	if (channel<=4){
		outportb(0x0a,channel);
	}else{
		outportb(0xd4,channel);
	}
}

void dma_unmask_all(){
	outportb(0xdc,0xff);
}

void dma_reset(){
	outportb(0x0c,0xff);
}

void dma_reset_flipflop(){
	outportb(0xd8,0xff);
}

void dma_set_address(uint8_t low, uint8_t high){
	outportb(0x04,low);
	outportb(0x04,high);
}

void dma_set_count(uint8_t low, uint8_t high){
	outportb(0x05,low);
	outportb(0x05,high);
}

void dma_set_epr(uint8_t addr){
	outportb(0x81,addr);
}

export void _cdecl dma_set_read(){
	dma_mask_channel(2);
	outportb(0x0b,0x56);
	dma_unmask_all();
}

export void _cdecl dma_set_write(){
	dma_mask_channel(2);
	outportb(0x0b,0x5a);
	dma_unmask_all();
}

export bool _cdecl dma_initialize_floppy(uint8_t* buffer, unsigned length){
	union{
		uint8_t byte[4];//Lo[0], Mid[1], Hi[2]
		unsigned long l;
	}a, c;

	a.l=(unsigned)0x500;//buffer
	c.l=(unsigned)length-1;

	//Check for buffer issues
	if ((a.l >> 24) || (c.l >> 16) || (((a.l & 0xffff)+c.l) >> 16)){
#ifdef _DEBUG
		_asm{
			mov		eax, 0x1337
			cli
			hlt
		}
#endif
		return false;
	}

	dma_reset();//Hard reset
	dma_mask_channel(2);//Mask channel 2
	dma_reset_flipflop();//Flipflop reset

	dma_set_address(a.byte[0],a.byte[1]);//Buffer address
	dma_set_epr(a.byte[2]);//Set page register

	dma_reset_flipflop();//Flipflop reset

	dma_set_count(c.byte[0],c.byte[1]);//Set count
	
	outportb(0x0b,0x56);//Set the dma to read when initialized

	dma_unmask_all();//Unmask channel 2

	return true;
}
(Also it skips 3 bytes)

So I guess what I'm asking is does anyone see anything wrong with that?
If not, any ideas on what could possibly cause this?
User avatar
Creature
Member
Member
Posts: 548
Joined: Sat Dec 27, 2008 2:34 pm
Location: Belgium

Re: FDC prints junk?

Post by Creature »

Are you sure you placed the DMA buffer at a physical address below 16 MB? I believe the DMA requires it to be somewhere below that area. I'm also not sure about the 'dma_mask_channel' function, I never knew too much about bit shifting and such, but I'm not sure it's being done correctly. When I want to mask channel 2, this is what I do:

Code: Select all

WriteByte(0x0A, 0x06);
Your code gives this:

Code: Select all

WriteByte(0x0A, (1 << (channel - 1)));
Where if channel = 2, the byte written would be (1 << 1), which sets bit 1 and I believe is equal to 0x02. Again, I'm not sure about the DMA code, but it might be a problem.

Besides this, it could also be a problem with your floppy sector reading code (or whatever reading code and functions you've implemented), so it might be useful posting those as well.
When the chance of succeeding is 99%, there is still a 50% chance of that success happening.
User avatar
-m32
Member
Member
Posts: 120
Joined: Thu Feb 21, 2008 5:59 am
Location: Ottawa, Canada

Re: FDC prints junk?

Post by -m32 »

Yeah, I think you need to read the Wiki very carefully: http://wiki.osdev.org/DMA
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Re: FDC prints junk?

Post by Dex »

Also zero you DMA buffer to see if your driver works at all, as you could be printing random data at the buffer address.
Note: it should in most cases work or not work, not half work ;)
Post Reply