/* 
DMA.C -- uses Virtual DMA Services (VDS)

sample output:
DMA Services 1.0
Maximum DMA buffer: 196864 bytes
Automatic remap not supported
All memory not physically contiguous
*/ 
 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h>
#include <dos.h> 
#include <pharlap.h>
#include <hw386.h>
 
#define CLEAR(x)        memset(&x, 0, sizeof(x)) 
 
typedef struct { 
    unsigned long size; 
    unsigned long linear_ofs; 
    unsigned short seg; 
    unsigned short buff_id; 
    unsigned long phys_addr; 
    } DDS;  /* DMA descriptor structure */ 
 
void fail(char *s) { puts(s); exit(1); } 
 
int lin_eq_phys(void)   // is linear==physical? 
{ 
    REALPTR BiosRealp;
    UCHAR BiosFlags;
    RP_SET(BiosRealp, 0x7B, 0x40);  // Bios flags at 0040:007B
    BiosFlags = PeekRealByte(BiosRealp);
    return (!(BiosFlags & 0x20));   // check VDS present bit
} 
 
int vds_get_version(unsigned *pmaj, unsigned *pmin,  
                    unsigned *pmaxbuff, unsigned *pfeatures) 
{ 
    SWI_REGS r; 
    CLEAR(r); 
    r.eax = 0x8102;
    r.edx = 0; 
    _dx_real_int(0x4b, &r);   // VDS uses INT 4Bh 
    if (r.flags & EF_CF)
        return 0;   // carry set -- VDS Get Version failed 
    *pmaj = (r.eax >> 8) & 0xFF;
    *pmin = r.eax & 0xFF;
    *pmaxbuff = (r.esi << 16) + (r.edi & 0xFFFF); 
    *pfeatures = r.edx & 0xFFFF; 
    return 1; 
} 
     
main() 
{ 
    unsigned maj, min, maxbuff, features; 
     
    if (lin_eq_phys()) 
        fail("linear == physical"); // no VDS 
             
    if (! vds_get_version(&maj, &min, &maxbuff, &features)) 
        fail("VDS Get Version failed"); 
    
    // possibly check maj/min for reasonableness
     
    printf("DMA Services %d.%d\n", maj, min); 
    printf("Maximum DMA buffer: %u bytes\n", maxbuff); 
    if (features & 1) puts("PC/XT bus architecture (first meg only"); 
    if (features & 2) puts("Physical buffer/remap region in first meg"); 
    if (features & 4) puts("Automatic remap supported"); 
    else              puts("Automatic remap not supported"); 
    if (features & 8) puts("All memory physically contiguous"); 
    else              puts("All memory not physically contiguous"); 
     
    return 0; 
} 
