252 lines
3.3 KiB
C
252 lines
3.3 KiB
C
|
|
|
|
#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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|