FDC-DMA problem

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
Al

FDC-DMA problem

Post by Al »

Hello All,

I am writing a floppy driver and am trying to make sure my DMA code is correct. The code I have I got from somewhere else, so I have almost no idea what it means. I understand some, but not enough to know if there are problems with it.

For now, I am just trying to write to video memory(0xa0000), just to see if the floppy read sector worked.

Can you tell me if this should work?
I call it with:
Setup_DMA(0x2, buffer, 512, 1); //buffer is ignored; 0xa0000
//is used instead, 1 means floppy to dma, 512 bytes, channel 2

Code: Select all

typedef unsigned short int ushort;
typedef unsigned long int ulong;
typedef unsigned char uchar;

ushort AddrP[4] = {0x00, 0x02, 0x04, 0x06};
ushort PageP[4] = {0x87, 0x83, 0x81, 0x82};
ushort CountP[4] = {0x01, 0x03, 0x05, 0x07};
int Setup_DMA(int Channel, char *Buffer, ulong Length, uchar Direction) {
//Pre:  0 <= Channel <= 3
//      Buffer < 1048576
//      0 < Length <= 65536
//      Direction == 0 if Memory-to-I/O, Direction == 1 if I/O-to-Memory
//
//Post: Return 0 if successful, else return 1.

 uchar Out;
 uchar LSB;
 uchar MSB;
 uchar Page;
 Out = 0x40;

//Only support DMA channels 1-3
 if(Channel > 3) return 1;

 Out = Out | Channel;

 if(Direction == 0) Out = Out | 0x08;
 else if(Direction == 1) Out = Out | 0x04;
 else return 1;

//Only does DMA in the first 1Meg (for now).  And only if thebuffer does notcross a 64K page boundary.
 //if((ulong)Buffer > 1048576 || (ulong)Buffer >> 16 != ((ulong)Buffer + (Length - 1)) >> 16) return 1;

 LSB = 0x0; //(uchar)Buffer;
 MSB = 0x0; //(uchar)((ulong)Buffer >> 8);
 Page = 0xa; //(uchar)((ulong)Buffer >> 16);

 if(Length > 65536 || Length == 0) return 1;

 Length--;

 //Mask this DMA channel.
 outportb(0x0A, (uchar)Channel | 4);

 //Send the mode.
 outportb(0x0B, Out);

 //Clear LSB/MSB flip/flop
 outportb(0x0C, 0);

 //Send the address & page.
 outportb(AddrP[Channel], LSB);
 outportb(AddrP[Channel], MSB);
 outportb(PageP[Channel], Page);

 //Clear LSB/MSB flip/flop
 outportb(0x0C, 0);

 //Send the length of transfer.
 outportb(CountP[Channel], (uchar)Length);
 outportb(CountP[Channel], (uchar)(Length >> 8));

 //Unmask this DMA channel.
 outportb(0x0A, (uchar)Channel);

 return 0;

Post Reply