È®Àå º¸µå·ÎÀÇ DMA ¸Þ¸ð¸® Àü¼Û ±¸¼º °³¿ä
DMA ±â´É Á¦°øÇÏ´Â È®Àå º¸µå¿¡´Â, ±¸¼ºÀ¸·Î¼ DMA Àü¼ÛóÀÇ ¸Þ¸ð¸®¸¦ ¸ÞÀÎ ¸Þ¸ð¸®·Î Çϴ ŸÀÔÀÇ °Í°ú È®Àå
º¸µå³»ÀÇ µà¾ó Æ÷Æ® RAM¿¡ ½ÇÀåÇϴ ŸÀÔÀÇ °ÍÀÌ ÀÖ½À´Ï´Ù. ÀÌÇÏ¿¡ ±× 2°³ÀÇ Å¸ÀÔÀÇ ±¸¼ºÀ» ±âÀçÇÕ´Ï´Ù.
1.È®Àå º¸µå¿¡ DMA¿ë ¸Þ¸ð¸® ¾øÀ½ÀÇ ±¸¼º
È®Àå º¸µå¿¡, DMA¿ë ¸Þ¸ð¸®°¡ ¾ø´Â °æ¿ì¿¡´Â, ¸ÞÀÎ ¸Þ¸ð¸®ÀÇ ¹°¸® ÁÖ¼Ò¸¦ È®Àå º¸µå¿¡ ¼³Á¤Çϰí, DMA
Àü¼ÛóÀÇ ¸Þ¸ð¸®·Î ÇÕ´Ï´Ù.

2.È®Àå º¸µå¿¡ DMA¿ë ¸Þ¸ð¸®À¯ÀÇ ±¸¼º
È®Àå º¸µå¿¡, DMA¿ë ¸Þ¸ð¸®°¡ ÀÖ´Â °æ¿ì¿¡´Â, È®Àå º¸µå·ÎºÎÅÍ DMA¿ë ¸Þ¸ð¸®ÀÇ ÁÖ¼Ò(¹°¸® ÁÖ¼Ò)¸¦ ÃëµæÇØ,
DMA ¿Ï·á¸¦ È®ÀÎ ÈÄ¿¡, AP°¡ È®Àå º¸µåÀÇ DMA¿ë ¸Þ¸ð¸®·ÎºÎÅÍ ¸ÞÀÎ ¸Þ¸ð¸®¿¡, µ¥ÀÌÅÍ Àü¼ÛµîÀ» ½Ç½ÃÇÕ´Ï´Ù.

È®Àå º¸µå·ÎÀÇ DMA ÀÌ¿ë¹ýÇØ¼³
1.È®Àå º¸µå¿¡ DMA¿ë ¸Þ¸ð¸® ¾øÀ½À¸·ÎÀÇ ÀÌ¿ë ¹æ¹ý
È®Àå º¸µå¿¡ DMA¿ë ¸Þ¸ð¸®¸¦ ½ÇÀåÇϰí ÀÖÁö ¾Ê´Â °æ¿ìÀÇ ÀÌ¿ë ¼ø¼¸¦ ÀÌÇÏ¿¡
±âÀçÇÕ´Ï´Ù.
1. È®Àå º¸µåÀÇ Á¤º¸ Ãëµæ
È®Àå º¸µåÀÇ Á¦¾î Á¤º¸(I/OÆ÷Åä º£À̽º ÁÖ¼Ò, IRQ ¹øÈ£)µîÀ» ÃëµæÇÕ´Ï´Ù.PCI º¸µåÀÇ °æ¿ì¿¡´Â, PCI
ÄÁÇDZַ¹ÀÌ¼Ç ·¹Áö½ºÅͺ¸´Ù ÃëµæÇØ, ISA º¸µåÀÇ °æ¿ì¿¡´Â, º¸µå»óÀÇ ½ºÀÄ¡µî¿¡ ÀÇÇÑ ¼³Á¤ÀÌ µË´Ï´Ù.
¡Ø¿¹£ºPCI
º¸µå·ÎºÎÅÍÀÇ Á¤º¸ Ãëµæ(ÇÔ¼ö À̹ÌÁö)
// PCI º¸µå °ËÃâ
dev.wVendorId = 0x1147; // º¥´õ IDÀÇ ¼³Á¤¿¹(È®Àå º¸µå¿¡ ´ëÀÀÀÇ Á¤º¸
// (À»)¸¦ ¼³Á¤ÇÕ´Ï´Ù.)
dev.wDeviceId = 0x0DC5; // µð¹ÙÀ̽º IDÀÇ ¼³Á¤¿¹(È®Àå º¸µå¿¡ ´ëÀÀÀÇ Á¤º¸
// (À»)¸¦ ¼³Á¤ÇÕ´Ï´Ù.)
dev.wDeviceIndex = 0; // ÃÖÃÊ·Î ¹ß°ßµÈ µð¹ÙÀ̽º¸¦ ÃëµæÇÏ´Â °æ¿ìÀÇ ÁöÁ¤
if (PciFindDevice(&dev) == FALSE)
return ( -1 ); // ÁöÁ¤ µð¹ÙÀ̽º°¡ ¹ß°ßµÇÁö ¾Ê±â ¶§¹®¿¡ ¿¡·¯¸¦ µ¹·ÁÁÝ´Ï´Ù.
dwBaseAdd = dev.dwBaseAddr[0] & 0xFFFC; // I/OÆ÷Åä º£À̽º ÁÖ¼Ò¸¦ Ãëµæ
byIrqNo = dev.byIntLine ; // IRQ ¹øÈ£¸¦ Ãëµæ
return ( 0 ); // ÁöÁ¤ µð¹ÙÀ̽ºÀÇ °ËÃâ ¼º°ø
2. DMA¿ë ¸Þ¸ð¸®ÀÇ È®º¸¿Í ¼³Á¤
DMA¿ëÀÇ ¸Þ¸ð¸®´Â, ¸ÞÀÎ ¸Þ¸ð¸®·Î ºÎÅÍ ÇÊ¿ä »çÀÌÁ È®º¸ÇØ, È®Àå º¸µå¿¡´Â, È®º¸ÇÑ ¸ÞÀÎ ¸Þ¸ð¸®ÀÇ ÁÖ¼ÒÀÇ ¹°¸®
ÁÖ¼Ò ¹×, È®º¸ÇÑ ¸ÞÀÎ ¸Þ¸ð¸®ÀÇ »çÀÌÁ ¼³Á¤ÇÕ´Ï´Ù.
¡Ø¿¹£ºDMA¿ë
¸Þ¸ð¸®ÀÇ È®º¸¿Í È®Àå Ä«µå¿¡ÀÇ DMA ÁÖ¼Ò ÁöÁ¤(ÇÔ¼ö À̹ÌÁö)
// ADº¯È¯ DMA Àü¼Û¿ëÀ¸·Î ¸Þ¸ð¸®ÀÇ È®º¸£º80 KBÈ®º¸ÀÇ ¿¹
if((pMem = AllocateRtMemory(4096*20)) == NULL)
return ( -1 ); // ¸Þ¸ð¸®ÀÇ È®º¸¿¡ ½ÇÆÐÇßÀ¸¹Ç·Î ¿¡·¯¸¦ µ¹·ÁÁÝ´Ï´Ù.
// DMA¿ë ¸Þ¸ð¸®ÀÇ ¹°¸® ÁÖ¼Ò¸¦ Ãëµæ
if((dwAdd = GetRtPhysicalAddress(pMem, 4096*20, 0)) == BAD_PHYSICAL_ADDRESS)
return ( -1 ); // ¹°¸® ÁÖ¼ÒÀÇ Ãëµæ¿¡ ½ÇÆÐÇßÀ¸¹Ç·Î ¿¡·¯¸¦ µ¹·ÁÁÝ´Ï´Ù.
// È®Àå º¸µå¿¡ DMA¿ë ¸Þ¸ð¸®¾Æµå·¹½º¿Í ¸Þ¸ð¸®ÀÇ »çÀÌÁ ¼³Á¤ÇÕ´Ï´Ù.
// ÀÌÇÏ´Â ¼³Á¤¿¹·Î, ¼³Á¤ ¹æ¹ý¹ýÀº, È®Àå º¸µå¿¡ ÀÇÇØ »ç¾çÀÌ ´Ù¸£±â ¶§¹®¿¡ È®ÀÎÀÌ ÇÊ¿äÇÕ´Ï´Ù.
outword((WORD)(dwBaseAdd + 0x24), dwAdd); // DMA¿ë ¸Þ¸ð¸®º£À̽º¾Æµå·¹½ºÀÇ ¼³Á¤
outword((WORD)(dwBaseAdd + 0x2C), 4096*20); // DMA¿ë ¸Þ¸ð ¸®»çÀÌÁîÀÇ ¼³Á¤
return ( 0 ); // ¸Þ¸ð¸® È®º¸ ¼º°ø
3. DMA °³½ÃÀÇ ¼³Á¤
DMA Àü¼ÛÀÇ °³½Ã(È®Àå º¸µåÀÇ ±â´É °³½Ã) ¿ä±¸¸¦ ½Ç½ÃÇÕ´Ï´Ù.
DMA Àü¼Û °³½Ã ¿ä±¸´Â, È®Àå º¸µåÀÇ
»ç¾ç¿¡ ÀÇÇØ ´Ù¸£±â ¶§¹®¿¡, È®Àå º¸µåÀÇ »ç¾çÀ» È®ÀÎÇÒ Çʿ䰡 ÀÖ½À´Ï´Ù.
4.DMA Àü¼Û ¿Ï·áÀÇ °¨½Ã
DMA Àü¼ÛÀÇ ¿Ï·á(È®Àå º¸µåÀÇ Ã³¸® ¿Ï·á)´Â, ÀÎÅÍ·´Æ® À̺¥Æ®³ª, I/OÆ÷Åäµ¶ÀÔÀ¸·Î ½ºÅ×ÀÌÅͽº¸¦ È®ÀÎÇÏ´Â
¹æ¹ýÀÌ ÀÖ½À´Ï´Ù.
¸®¾óŸÀÓ¼ºÀ» ¿ä±¸ÇÏ´Â °æ¿ì¿¡´Â, ó¸® ¹æ¹ýÀ¸·Î¼´Â, DMA Àü¼ÛÀÇ ¿Ï·á¸¦ ÀÎÅÍ·´Æ® À̺¥Æ®¿¡ ÀÇÇØ, °ËÁöÇÏ´Â ¹æ¹ýÀ¸·Î
ó¸®ÇÕ´Ï´Ù.
DMA Àü¼Û ¿Ï·áÀÇ °¨½Ã ¹æ¹ý ÀÚ¼¼ÇÑ °ÍÀº, È®Àå º¸µå »ç¾ç¿¡ ÀÇÇØ ´Ù¸£±â ¶§¹®¿¡, È®Àå º¸µåÀÇ »ç¾çÀ¸·Î È®ÀÎÇØ
ÁÖ¼¼¿ä.
INtime·ÎÀÇ ÀÎÅÍ·´Æ® ó¸® ¹æ¹ýÀº, º°µµ ÀڷḦ ÂüÁ¶ÇØ ÁÖ¼¼¿ä.
¡Ø¿¹£ºÀÎÅÍ·´Æ®
Çڵ鷯³»¿¡¼ÀÇ DMA ¿Ï·á °¨½Ã^
__INTERRUPT void IntHandler( WORD wCSRA, WORD wLevel, PVOID pv)
{
WORD wIntrStatus ; // ÀÎÅÍ·´Æ® ½ºÅ×ÀÌÅͽºÀÇ º¸Á¸¿ë ¹öÆÛ
__SHARED_INTERRUPT_PROLOG(); // ÀÎÅÍ·´Æ® Çڵ鷯ÀÇ °³½Ã
// ÀÎÅÍ·´Æ® ½ºÅ×ÀÌÅͽº Àбâ(È®Àå º¸µå¿¡ ÀÇÇØ »ç¾çÀÌ ´Ù¸£±â ¶§¹®¿¡ È®ÀÎÀÌ ÇÊ¿äÇÕ´Ï´Ù.)
wIntrStatus = inbyte( stInitDataTb.dwBaseAdd + 0x38 );
SignalRtInterruptThread(wLevel); // ÀÎÅÍ·´Æ® ½º·¿µåÀÇ ±âµ¿
__SHARED_INTERRUPT_RETURN(); // ÀÎÅÍ·´Æ® Çڵ鷯ÀÇ Á¾·á
} // end of IntHandler()
2. È®Àå º¸µå¿¡ DMA¿ë ¸Þ¸ð¸®À¯·ÎÀÇ ÀÌ¿ë ¹æ¹ý
È®Àå º¸µå¿¡ DMA¿ë ¸Þ¸ð¸®¸¦ ½ÇÀåÇϰí ÀÖ´Â °æ¿ìÀÇ ÀÌ¿ë ¼ø¼¸¦ ÀÌÇÏ¿¡
±âÀçÇÕ´Ï´Ù.
1. È®Àå º¸µåÀÇ Á¤º¸ Ãëµæ
È®Àå º¸µåÀÇ Á¦¾î Á¤º¸(DMA¿ë ¸Þ¸ð¸®½ÇÁÖ¼Ò, I/OÆ÷Åä º£À̽º ÁÖ¼Ò, IRQ ¹øÈ£)µîÀ»
ÃëµæÇÕ´Ï´Ù.
PCI º¸µåÀÇ °æ¿ì¿¡´Â, PCI ÄÁÇDZַ¹ÀÌ¼Ç ·¹Áö½ºÅͺ¸´Ù ÃëµæÇØ, ISA º¸µåÀÇ °æ¿ì¿¡´Â, º¸µå»óÀÇ ½ºÀÄ¡µî¿¡ ÀÇÇÑ ¼³Á¤ÀÌ
µË´Ï´Ù.
¡Ø¿¹£ºPCI
º¸µå·ÎºÎÅÍÀÇ Á¤º¸ Ãëµæ(ÇÔ¼ö À̹ÌÁö)
// PCI º¸µå °ËÃâ
dev.wVendorId = 0x1147; // º¥´õ IDÀÇ ¼³Á¤¿¹(È®Àå º¸µå¿¡ ´ëÀÀÀÇ Á¤º¸
// (À»)¸¦ ¼³Á¤ÇÕ´Ï´Ù.)
dev.wDeviceId = 0x0DC5; // µð¹ÙÀ̽º IDÀÇ ¼³Á¤¿¹(È®Àå º¸µå¿¡ ´ëÀÀÀÇ Á¤º¸
// (À»)¸¦ ¼³Á¤ÇÕ´Ï´Ù.)
dev.wDeviceIndex = 0; // ÃÖÃÊ·Î ¹ß°ßµÈ µð¹ÙÀ̽º¸¦ ÃëµæÇÏ´Â °æ¿ìÀÇ ÁöÁ¤
if (PciFindDevice(&dev) == FALSE)
return ( -1 ); // ÁöÁ¤ µð¹ÙÀ̽º°¡ ¹ß°ßµÇÁö ¾Ê±â ¶§¹®¿¡ ¿¡·¯¸¦ µ¹·ÁÁÝ´Ï´Ù.
dwDmaAdd = dev.dwBaseAddr[0] & 0xFFFFFFF0;// DMA¿ë ¸Þ¸ð¸® ¹°¸® ÁÖ¼Ò¸¦ Ãëµæ
dwBaseAdd = dev.dwBaseAddr[1] & 0xFFFC; // I/OÆ÷Åä º£À̽º ÁÖ¼Ò¸¦ Ãëµæ
byIrqNo = dev.byIntLine ; // IRQ ¹øÈ£¸¦ Ãëµæ
return ( 0 ); // ÁöÁ¤ µð¹ÙÀ̽ºÀÇ °ËÃâ ¼º°ø
2. È®Àå º¸µåÀÇ DMA¿ë ¸Þ¸ð¸®¸¦ 4 K¹ÙÀÌÆ®ÀÇ ¹Ù¿î´Ù¸® À§Ä¡¿¡ Á¶Á¤ INtime¿¡¼´Â, ½ÇÁÖ¼Ò¿¡ ´ëÇØ¼, ¾×¼¼½º¸¦ ½Ç½ÃÇÏ·Á¸é ,
½ÇÁÖ¼Ò¸¦ ¹öÃß¾ó ÁÖ¼Ò ½ºÆäÀ̽º¿¡ ÇҺθ¦ ½Ç½ÃÇÒ ÇÊ¿ä.»ó, ¹öÃß¾ó ÁÖ¼Ò ½ºÆäÀ̽º¿¡ ÇÒ´çÇÏ´Â °æ¿ì¿¡´Â, ¹°¸® ÁÖ¼ÒÀÇ ¼±µÎ ÁÖ¼Ò°¡, 4 K¹ÙÀÌÆ® °æ°è¿¡ ¾ó¶óÀÌ¸ÕÆ® µÇ¾î ÀÖÀ» Çʿ䰡 ÀÖ½À´Ï´Ù.
¡Ø¿¹£º4
K¹ÙÀÌÆ® °æ°è¿¡ÀÇ ¾ó¶óÀÌ¸ÕÆ®

¡ß»ó±â
±¸¼ºÀ¸·ÎÀÇ ÇÁ·Î±×·¥¿¹(ÇÔ¼ö À̹ÌÁö)
// ¹öÃß¾ó ÁÖ¼Ò ½ºÆäÀ̽º¿¡ÀÇ ÇҺΠ¼±µÎ ÁÖ¼Ò ¼³Á¤
dwDmaMAddr = dwDmaAdd ?(dwDmaAdd % 4096);
// ¹öÃß¾ó ÁÖ¼Ò ½ºÆäÀ̽º¿¡ÀÇ ÇҺΠ»çÀÌÁî ¼³Á¤(0x8000 ´Â, È®Àå º¸µå
// ÇÏÁö¸¸ Á¦°øÇÏ´Â DMA¿ë ¸Þ¸ð ¸®»çÀÌÁî)
dwDmaMSize = ((dwDmaMAddr + (dwDmaAdd % 4096) + 0x8000) / 4096 * 4096)
+ ((((dwDmaMAddr + (dwDmaAdd % 4096) + 0x8000) % 4096 + 4095)
/ 4096) * 4096);
// ¹öÃß¾ó ÁÖ¼Ò ½ºÆäÀ̽º¿¡ÀÇ ÇÒºÎ
if((pbyDmaAddr = MapRtPhysicalMemory(dwDmaMAddr, dwDmaMSize)) == FALSE)
return ( -1 ); // ¹öÃß¾ó ÁÖ¼Ò ½ºÆäÀ̽º¿¡ÀÇ ÇҺΰ¡ ½ÇÆÐÇßÀ¸¹Ç·Î ¿¡·¯
// (À»)¸¦ µ¹·ÁÁÝ´Ï´Ù.
// DMA¿ë ¸Þ¸ð¸® ¼±µÎ ÁÖ¼ÒÀÇ ¼³Á¤(ÁÖÀÇ£ºpbyDmaAddr ´Â BYTEÇü Æ÷ÀÎÅÍ º¯¼öÀÎ °Í)
pbyDmaAddr = pbyDmaAddr + (dwDmaAdd % 4096);
return ( 0 ); // ¹öÃß¾ó ÁÖ¼Ò ½ºÆäÀ̽º¿¡ÀÇ ÇҺΠ¼º°ø
3. DMA °³½ÃÀÇ ¼³Á¤
¡¸È®Àå º¸µå¿¡ DMA¿ë ¸Þ¸ð¸® ¾øÀ½À¸·ÎÀÇ ÀÌ¿ë ¹æ¹ý¡¹°ú °°ÀÌ È®Àå º¸µåÀÇ »ç¾ç¿¡ ÀÇÇØ ´Ù¸£±â ¶§¹®¿¡, È®Àå
º¸µåÀÇ »ç¾çÀ¸·Î È®ÀÎÇØ ÁÖ¼¼¿ä.
4. DMA ¿Ï·áÀÇ °¨½Ã
¡¸È®Àå º¸µå¿¡ DMA¿ë ¸Þ¸ð¸® ¾øÀ½À¸·ÎÀÇ ÀÌ¿ë ¹æ¹ý¡¹°ú °°ÀÌ È®Àå º¸µåÀÇ »ç¾ç¿¡ ÀÇÇØ ´Ù¸£±â ¶§¹®¿¡, È®Àå
º¸µåÀÇ »ç¾çÀ¸·Î È®ÀÎÇØ ÁÖ¼¼¿ä.