ReactOS 0.4.15-dev-8061-g57b775e
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}
#define NULL
Definition: types.h:112
static BYTE WINAPI DmaReadPort(USHORT Port)
Definition: dma.c:52
static BYTE WINAPI DmaPageReadPort(USHORT Port)
Definition: dma.c:324
static VOID WINAPI DmaWritePort(USHORT Port, BYTE Data)
Definition: dma.c:162
static VOID WINAPI DmaPageWritePort(USHORT Port, BYTE Data)
Definition: dma.c:351
VOID RegisterIoPort(USHORT Port, EMULATOR_INB_PROC InHandler, EMULATOR_OUTB_PROC OutHandler)
Definition: io.c:320

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
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}
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
#define SetLastError(x)
Definition: compat.h:752
#define DMA_CONTROLLERS
Definition: dma.h:15
#define DMA_CONTROLLER_CHANNELS
Definition: dma.h:16
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:46
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
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
#define min(a, b)
Definition: monoChain.cc:55
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
BYTE * PBYTE
Definition: pedump.c:66
WORD CurrElemCnt
Definition: dma.h:23
WORD BaseElemCnt
Definition: dma.h:21
BYTE Mode
Definition: dma.h:24
WORD BaseAddress
Definition: dma.h:20
WORD CurrAddress
Definition: dma.h:22
BYTE Command
Definition: dma.h:36
DMA_CHANNEL DmaChannel[DMA_CONTROLLER_CHANNELS]
Definition: dma.h:29
BYTE Mask
Definition: dma.h:38
BYTE Status
Definition: dma.h:39
FAST486_STATE EmulatorContext
Definition: cpu.c:39
static DMA_CONTROLLER DmaControllers[DMA_CONTROLLERS]
Definition: dma.c:29
static DMA_PAGE_REGISTER DmaPageRegisters[DMA_CONTROLLERS *DMA_CONTROLLER_CHANNELS]
Definition: dma.c:32
VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:142
VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:186
uint32_t ULONG
Definition: typedefs.h:59
int ret
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
unsigned char BYTE
Definition: xxhash.c:193

Referenced by VDDRequestDMA().