#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 } } }