Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

251 lines
3.3 KiB

#define DMASTATUSREG 0x8
#define DMA8SINGLEMASKREG 0xa
#define DMA16SINGLEMASKREG 0xd4
#define DMA8MASTERMASKREG 0xf
#define DMA16MASTERMASKREG 0xde
#define DMA8CLEARFLIPFLOP 0xc
#define DMA16CLEARFLIPFLOP 0xd8
#define DMA8BASE 0x0
#define DMA16BASE 0xc0
ULONG page[8] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
VOID __inline UnmaskDmaChannel(ULONG channel)
{
ASSERT ( channel<8 && channel!=4 );
if (channel<4) {
__asm {
mov eax,channel
out DMA8SINGLEMASKREG,al
}
}
else if (channel<8) {
__asm {
mov eax,channel
sub eax,4
out DMA16SINGLEMASKREG,al
}
}
}
VOID __inline MaskDmaChannel(ULONG channel)
{
ASSERT ( channel<8 && channel!=4 );
if (channel<4) {
__asm {
mov eax,channel
or eax,0x4
out DMA8SINGLEMASKREG,al
}
}
else if (channel<8) {
__asm {
mov eax,channel
out DMA16SINGLEMASKREG,al
}
}
}
// This reads the DMA controller mask register.
ULONG __inline ReadDMAMask(VOID)
{
__asm {
xor eax,eax
in al,DMA8MASTERMASKREG
ror eax,4
in al,DMA16MASTERMASKREG
and al,0xf
rol eax,4
}
}
VOID __inline ReadDmaPosition(ULONG channel, PULONG pCurrentDmaPosition)
{
ASSERT ( channel<8 && channel!=4 );
if (channel<4) {
__asm {
// First clear the flip flop.
xor eax,eax
out DMA8CLEARFLIPFLOP, al
// Read low byte and save it away.
mov edx, channel
shl edx, 1
in al, dx
ror eax,8
// Read high byte and save it away.
in al, dx
ror eax,8
// Read page byte.
shl edx, 1
add edx, offset page
mov edx, dword ptr[edx]
in al, dx
ror eax,8
// Read hi-page byte. Ignore if 0xff.
add edx,0x400
in al, dx
sub al, 0xff
jz done8
add al, 0xff
done8:
ror eax,8
mov edx, pCurrentDmaPosition
mov dword ptr [edx], eax
}
}
else if (channel<8) {
__asm {
// First clear the flip flop.
xor eax,eax
out DMA16CLEARFLIPFLOP, al
// Read low byte and save it away.
mov edx, channel
sub edx, 4
shl edx, 2
add edx, DMA16BASE
in al, dx
ror eax,8
// Read high byte and save it away.
// We left shift bottom 16 bits by 1 and or top bit into page.
in al, dx
ror eax,7
mov ah, al
// Read page byte.
mov edx, channel
shl edx, 2
add edx, offset page
mov edx, dword ptr[edx]
in al, dx
// Or in bit 15 of word address and save away page byte.
or al, ah
ror eax,8
// Read hi-page byte. Ignore if 0xff.
add edx,0x400
in al, dx
sub al, 0xff
jz done16
add al, 0xff
done16:
ror eax,8
mov edx, pCurrentDmaPosition
mov dword ptr [edx], eax
}
}
}
VOID __inline ReadDmaCount(ULONG channel, PULONG pCurrentDmaCount)
{
ASSERT ( channel<8 && channel!=4 );
if (channel<4) {
__asm {
// First clear the flip flop.
xor eax,eax
out DMA8CLEARFLIPFLOP, al
// Read low byte and save it away.
mov edx, channel
shl edx, 1
inc edx
in al, dx
ror eax,8
// Read high byte and fixup count.
in al, dx
rol eax,8
mov edx, pCurrentDmaCount
mov dword ptr [edx], eax
}
}
else if (channel<8) {
__asm {
// First clear the flip flop.
xor eax,eax
out DMA16CLEARFLIPFLOP, al
// Read low byte and save it away.
mov edx, channel
sub edx, 4
shl edx, 2
add edx, 2
add edx, DMA16BASE
in al, dx
ror eax,8
// Read high byte and fixup count.
in al, dx
rol eax,9
mov edx, pCurrentDmaCount
mov dword ptr [edx], eax
}
}
}