ReactOS  0.4.14-dev-390-g34947ad
dma.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _DMA_CHANNEL
 
struct  _DMA_CONTROLLER
 
struct  _DMA_PAGE_REGISTER
 

Macros

#define DMA_CONTROLLERS   2
 
#define DMA_CONTROLLER_CHANNELS   4
 

Typedefs

typedef struct _DMA_CHANNEL DMA_CHANNEL
 
typedef struct _DMA_CHANNELPDMA_CHANNEL
 
typedef struct _DMA_CONTROLLER DMA_CONTROLLER
 
typedef struct _DMA_CONTROLLERPDMA_CONTROLLER
 
typedef struct _DMA_PAGE_REGISTER DMA_PAGE_REGISTER
 
typedef struct _DMA_PAGE_REGISTERPDMA_PAGE_REGISTER
 

Functions

DWORD DmaRequest (IN WORD iChannel, IN OUT PVOID Buffer, IN DWORD length)
 
VOID DmaInitialize (VOID)
 

Macro Definition Documentation

◆ DMA_CONTROLLER_CHANNELS

#define DMA_CONTROLLER_CHANNELS   4

Definition at line 16 of file dma.h.

◆ DMA_CONTROLLERS

#define DMA_CONTROLLERS   2

Definition at line 15 of file dma.h.

Typedef Documentation

◆ DMA_CHANNEL

◆ DMA_CONTROLLER

◆ DMA_PAGE_REGISTER

◆ PDMA_CHANNEL

◆ PDMA_CONTROLLER

◆ PDMA_PAGE_REGISTER

Function Documentation

◆ DmaInitialize()

VOID DmaInitialize ( VOID  )

Definition at line 549 of file dma.c.

550 {
551  /* Register the I/O Ports */
552 
553  /* Channels 0(Reserved)..3 */
554  RegisterIoPort(0x00, DmaReadPort, DmaWritePort); /* Current(R) / Start(W) Address Register 0 (Reserved) */
555  RegisterIoPort(0x01, DmaReadPort, DmaWritePort); /* Current(R) / Base (W) Count Register 0 (Reserved) */
556  RegisterIoPort(0x02, DmaReadPort, DmaWritePort); /* Current(R) / Start(W) Address Register 1 */
557  RegisterIoPort(0x03, DmaReadPort, DmaWritePort); /* Current(R) / Base (W) Count Register 1 */
558  RegisterIoPort(0x04, DmaReadPort, DmaWritePort); /* Current(R) / Start(W) Address Register 2 */
559  RegisterIoPort(0x05, DmaReadPort, DmaWritePort); /* Current(R) / Base (W) Count Register 2 */
560  RegisterIoPort(0x06, DmaReadPort, DmaWritePort); /* Current(R) / Start(W) Address Register 3 */
561  RegisterIoPort(0x07, DmaReadPort, DmaWritePort); /* Current(R) / Base (W) Count Register 3 */
562 
563  RegisterIoPort(0x08, DmaReadPort, DmaWritePort); /* Status (Read) / Command (Write) Registers */
564  RegisterIoPort(0x09, NULL, DmaWritePort); /* Request Register */
565  RegisterIoPort(0x0A, NULL, DmaWritePort); /* Single Channel Mask Register */
566  RegisterIoPort(0x0B, NULL, DmaWritePort); /* Mode Register */
567  RegisterIoPort(0x0C, NULL, DmaWritePort); /* Flip-Flop Reset Register */
568  RegisterIoPort(0x0D, DmaReadPort, DmaWritePort); /* Intermediate (Read) / Master Reset (Write) Registers */
569  RegisterIoPort(0x0E, NULL, DmaWritePort); /* Mask Reset Register */
570  RegisterIoPort(0x0F, DmaReadPort, DmaWritePort); /* Multi-Channel Mask Register */
571 
572 
573  /* Channels 4(Reserved)..7 */
574  RegisterIoPort(0xC0, DmaReadPort, DmaWritePort); /* Current(R) / Start(W) Address Register 4 (Reserved) */
575  RegisterIoPort(0xC2, DmaReadPort, DmaWritePort); /* Current(R) / Base (W) Count Register 4 (Reserved) */
576  RegisterIoPort(0xC4, DmaReadPort, DmaWritePort); /* Current(R) / Start(W) Address Register 5 */
577  RegisterIoPort(0xC6, DmaReadPort, DmaWritePort); /* Current(R) / Base (W) Count Register 5 */
578  RegisterIoPort(0xC8, DmaReadPort, DmaWritePort); /* Current(R) / Start(W) Address Register 6 */
579  RegisterIoPort(0xCA, DmaReadPort, DmaWritePort); /* Current(R) / Base (W) Count Register 6 */
580  RegisterIoPort(0xCC, DmaReadPort, DmaWritePort); /* Current(R) / Start(W) Address Register 7 */
581  RegisterIoPort(0xCE, DmaReadPort, DmaWritePort); /* Current(R) / Base (W) Count Register 7 */
582 
583  RegisterIoPort(0xD0, DmaReadPort, DmaWritePort); /* Status (Read) / Command (Write) Registers */
584  RegisterIoPort(0xD2, NULL, DmaWritePort); /* Request Register */
585  RegisterIoPort(0xD4, NULL, DmaWritePort); /* Single Channel Mask Register */
586  RegisterIoPort(0xD6, NULL, DmaWritePort); /* Mode Register */
587  RegisterIoPort(0xD8, NULL, DmaWritePort); /* Flip-Flop Reset Register */
588  RegisterIoPort(0xDA, DmaReadPort, DmaWritePort); /* Intermediate (Read) / Master Reset (Write) Registers */
589  RegisterIoPort(0xDC, NULL, DmaWritePort); /* Mask Reset Register */
590  RegisterIoPort(0xDE, DmaReadPort, DmaWritePort); /* Multi-Channel Mask Register */
591 
592 
593  /* Channels Page Address Registers */
594  RegisterIoPort(0x87, DmaPageReadPort, DmaPageWritePort); /* Channel 0 (Reserved) */
595  RegisterIoPort(0x83, DmaPageReadPort, DmaPageWritePort); /* Channel 1 */
596  RegisterIoPort(0x81, DmaPageReadPort, DmaPageWritePort); /* Channel 2 */
597  RegisterIoPort(0x82, DmaPageReadPort, DmaPageWritePort); /* Channel 3 */
598  RegisterIoPort(0x8F, DmaPageReadPort, DmaPageWritePort); /* Channel 4 (Reserved) */
599  RegisterIoPort(0x8B, DmaPageReadPort, DmaPageWritePort); /* Channel 5 */
600  RegisterIoPort(0x89, DmaPageReadPort, DmaPageWritePort); /* Channel 6 */
601  RegisterIoPort(0x8A, DmaPageReadPort, DmaPageWritePort); /* Channel 7 */
602 }
static VOID WINAPI DmaWritePort(USHORT Port, BYTE Data)
Definition: dma.c:162
VOID RegisterIoPort(USHORT Port, EMULATOR_INB_PROC InHandler, EMULATOR_OUTB_PROC OutHandler)
Definition: io.c:320
smooth NULL
Definition: ftsmooth.c:416
static BYTE WINAPI DmaPageReadPort(USHORT Port)
Definition: dma.c:324
static VOID WINAPI DmaPageWritePort(USHORT Port, BYTE Data)
Definition: dma.c:351
static BYTE WINAPI DmaReadPort(USHORT Port)
Definition: dma.c:52

Referenced by EmulatorInitialize().

◆ DmaRequest()

DWORD DmaRequest ( IN WORD  iChannel,
IN OUT PVOID  Buffer,
IN DWORD  length 
)

Definition at line 386 of file dma.c.

389 {
390 /*
391  * NOTE: This function is adapted from Wine's krnl386.exe,
392  * DMA emulation by Christian Costa.
393  */
394  PDMA_CONTROLLER pDcp;
395  WORD Channel;
396 
397  DWORD i, Size, ret = 0;
398  BYTE RegMode, OpMode, Increment, Autoinit, TrMode;
399  PBYTE dmabuf = Buffer;
400 
401  ULONG CurrAddress;
402 
403  if (iChannel >= DMA_CONTROLLERS * DMA_CONTROLLER_CHANNELS)
404  {
406  return 0;
407  }
408 
409  pDcp = &DmaControllers[iChannel / DMA_CONTROLLER_CHANNELS];
410  Channel = iChannel % DMA_CONTROLLER_CHANNELS; // == (iChannel & 0x03)
411 
412  RegMode = pDcp->DmaChannel[Channel].Mode;
413 
414  DPRINT1("DMA_Command = %x length=%d\n", RegMode, length);
415 
416  /* Exit if the controller is disabled or the channel is masked */
417  if ((pDcp->Command & 0x04) || (pDcp->Mask & (1 << Channel)))
418  return 0;
419 
420  OpMode = (RegMode & 0xC0) >> 6;
421  Increment = !(RegMode & 0x20);
422  Autoinit = RegMode & 0x10;
423  TrMode = (RegMode & 0x0C) >> 2;
424 
425  /* Process operating mode */
426  switch (OpMode)
427  {
428  case 0:
429  /* Request mode */
430  DPRINT1("Request Mode - Not Implemented\n");
431  return 0;
432  case 1:
433  /* Single Mode */
434  break;
435  case 2:
436  /* Request mode */
437  DPRINT1("Block Mode - Not Implemented\n");
438  return 0;
439  case 3:
440  /* Cascade Mode */
441  DPRINT1("Cascade Mode should not be used by regular apps\n");
442  return 0;
443  }
444 
445  /* Perform one the 4 transfer modes */
446  if (TrMode == 4)
447  {
448  /* Illegal */
449  DPRINT1("DMA Transfer Type Illegal\n");
450  return 0;
451  }
452 
453  /* Transfer size : 8 bits for channels 0..3, 16 bits for channels 4..7 */
454  Size = (iChannel < 4) ? sizeof(BYTE) : sizeof(WORD);
455 
456  // FIXME: Handle wrapping?
457  /* Get the number of elements to transfer */
458  ret = min(pDcp->DmaChannel[Channel].CurrElemCnt, length / Size);
459  length = ret * Size;
460 
461  /* 16-bit mode addressing, see: http://wiki.osdev.org/ISA_DMA#16_bit_issues */
462  CurrAddress = (iChannel < 4) ? (DmaPageRegisters[iChannel].Page << 16) | ((pDcp->DmaChannel[Channel].CurrAddress << 0) & 0xFFFF)
463  : (DmaPageRegisters[iChannel].Page << 16) | ((pDcp->DmaChannel[Channel].CurrAddress << 1) & 0xFFFF);
464 
465  switch (TrMode)
466  {
467  /* Verification (no real transfer) */
468  case 0:
469  {
470  DPRINT1("Verification DMA operation\n");
471  break;
472  }
473 
474  /* Write */
475  case 1:
476  {
477  DPRINT1("Perform Write transfer of %d elements (%d bytes) at 0x%x %s with count %x\n",
478  ret, length, CurrAddress, Increment ? "up" : "down", pDcp->DmaChannel[Channel].CurrElemCnt);
479 
480  if (Increment)
481  {
482  EmulatorWriteMemory(&EmulatorContext, CurrAddress, dmabuf, length);
483  }
484  else
485  {
486  for (i = 0; i < length; i++)
487  {
488  EmulatorWriteMemory(&EmulatorContext, CurrAddress - i, dmabuf + i, sizeof(BYTE));
489  }
490  }
491 
492  break;
493  }
494 
495  /* Read */
496  case 2:
497  {
498  DPRINT1("Perform Read transfer of %d elements (%d bytes) at 0x%x %s with count %x\n",
499  ret, length, CurrAddress, Increment ? "up" : "down", pDcp->DmaChannel[Channel].CurrElemCnt);
500 
501  if (Increment)
502  {
503  EmulatorReadMemory(&EmulatorContext, CurrAddress, dmabuf, length);
504  }
505  else
506  {
507  for (i = 0; i < length; i++)
508  {
509  EmulatorReadMemory(&EmulatorContext, CurrAddress - i, dmabuf + i, sizeof(BYTE));
510  }
511  }
512 
513  break;
514  }
515  }
516 
517  /* Update DMA registers */
518  pDcp->DmaChannel[Channel].CurrElemCnt -= ret;
519  if (Increment)
520  pDcp->DmaChannel[Channel].CurrAddress += ret;
521  else
522  pDcp->DmaChannel[Channel].CurrAddress -= ret;
523 
524  /* Check for end of transfer */
525  if (pDcp->DmaChannel[Channel].CurrElemCnt == 0)
526  {
527  DPRINT1("DMA buffer empty\n");
528 
529  /* Update status register of the DMA chip corresponding to the channel */
530  pDcp->Status |= 1 << Channel; /* Mark transfer as finished */
531  pDcp->Status &= ~(1 << (Channel + 4)); /* Reset soft request if any */
532 
533  if (Autoinit)
534  {
535  /* Reload Current* registers to their initial values */
536  pDcp->DmaChannel[Channel].CurrAddress = pDcp->DmaChannel[Channel].BaseAddress;
537  pDcp->DmaChannel[Channel].CurrElemCnt = pDcp->DmaChannel[Channel].BaseElemCnt;
538  }
539  else
540  {
541  /* Set the mask bit for the channel */
542  pDcp->Mask |= (1 << Channel);
543  }
544  }
545 
546  return length;
547 }
BYTE Mask
Definition: dma.h:38
BYTE Status
Definition: dma.h:39
WORD BaseAddress
Definition: dma.h:20
VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:183
WORD CurrAddress
Definition: dma.h:22
static DMA_CONTROLLER DmaControllers[DMA_CONTROLLERS]
Definition: dma.c:29
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
unsigned short WORD
Definition: ntddk_ex.h:93
static DMA_PAGE_REGISTER DmaPageRegisters[DMA_CONTROLLERS *DMA_CONTROLLER_CHANNELS]
Definition: dma.c:32
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
#define DMA_CONTROLLER_CHANNELS
Definition: dma.h:16
int ret
#define ERROR_INVALID_ADDRESS
Definition: compat.h:96
unsigned char BYTE
Definition: mem.h:68
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define min(a, b)
Definition: monoChain.cc:55
WORD BaseElemCnt
Definition: dma.h:21
FAST486_STATE EmulatorContext
Definition: cpu.c:39
#define DPRINT1
Definition: precomp.h:8
BYTE Command
Definition: dma.h:36
DMA_CHANNEL DmaChannel[DMA_CONTROLLER_CHANNELS]
Definition: dma.h:29
unsigned int ULONG
Definition: retypes.h:1
WORD CurrElemCnt
Definition: dma.h:23
#define DMA_CONTROLLERS
Definition: dma.h:15
BYTE Mode
Definition: dma.h:24
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:42
BYTE * PBYTE
Definition: pedump.c:66
VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:139

Referenced by VDDRequestDMA().