#include "dwrite16.h--"


#define AUREAL 12EBh

#define AU8810   3
#define AU8820   1
#define AU8830   2

struct {
    word vendorID;  // 0
    word deviceID;  // 2
    word flags1;    // 4
    word flags2;    // 6
    byte revisionID;// 8
    byte programming_interface; //9
    byte sub_class_code; // A
    byte base_class_code; // B
    byte line_cache_size; // C
    byte latency_timer; // D
    byte header_type; // E
    byte reserved;  // F
    dword memory_address; // 10
    dword IO_Port1; // 14
    dword IO_Port2; // 18
    byte reserved1[16]; // 1C
    word subsystem_vendorID; // 2C
    word subsystemID; // 2E
    byte reserved2[12]; // 30
    byte IRQline; // 3C
    byte INT_Pin; // 3D
    byte Minimum_Grant; // 3E
    byte Maximum_Latency; // 3F
    byte Obseedians_Fix; // 40
    byte reserved3[256-40h];
} aureal_config;



word VORTEXMODEL() {
    
    SWITCH(aureal_config.deviceID) {

        CASE AU8820:
            AX = aureal_config.subsystem_vendorID;        
            IF (AX == 0x1092 ) {
                return "Sonic Impact A3D";
            } ELSE IF (AX == 0x5053 ) {
                return "Montego"; 
            } ELSE {
                return "AU8820 Vortex Digital Audio Processor";
            }
        
        CASE AU8830:
            AX = aureal_config.subsystem_vendorID;
            IF (AX == 0x1092 ) {
                return "Monster Sound II";
            } ELSE IF (AX == 0x5053 ) {
                return "Montego II"; 
            } ELSE {
                return "AU8830 Vortex 3D Digital Audio Processor";
            }
        
        CASE AU8810:
            return "AU8810 Vortex Digital Audio Processor";

        DEFAULT:            
            return "Unknown Vortex";
    }
}


word deviceH;
//word count = 0;

word main() {
///////////////////////////////////////////////////////////
//  check CPU 386+ ?
///////////////////////////////////////////////////////////
    AH = 70h;
    $pushf
    $push AX
    $popf
    $pushf
    $pop BX
    $popf
    DX = "386+ not found!";
    BH&=AH;
    $jz FATALERROR
//
//  check PCI BIOS
//
    AX = 0B101h;
    $int 1Ah
    $jc PCI_BIOS_ERROR
    $cmp ah, 0
    $jne PCI_BIOS_ERROR
    $cmp edx, 20494350h
    $je  PCI_BIOS_OK

PCI_BIOS_ERROR:
    DX = "PCI BIOS not found!"; 

FATALERROR:
    DWRITELN(DX);
    return -1;

PCI_BIOS_OK:
    
    // DWRITELN("PCI BIOS found!");
    BP = 0; // vortex sound cards counter

    for( CX = 1; CX <= 3; CX++ ) {
        for( SI = 0; SI < 0FFFFh; SI++ ) {
            $pushA

            AX = 0B102h;
            DX = AUREAL;
            $int 1Ah
            IF ( CARRYFLAG ) {
                $popA
                break; // !!!
            }
            deviceH = BX;
            FOR( DI = 0; DI < 256; DI += 2 ) {
                $push DI
                AX = 0B109h;
                BX = deviceH;
                $int 1Ah
                IF (CARRYFLAG) { AX = 0; } ELSE { AX = CX; }
                $pop DI
                DSWORD[ DI + #aureal_config ] = AX;
            }

            SWITCH( aureal_config.deviceID ) {
                CASE AU8810: AX = "----------  Vortex AU8810  -----------"; BREAK;
                CASE AU8820: AX = "-----  Vortex AU8820 (Vortex 1)  -----"; BREAK;
                CASE AU8830: AX = "-----  Vortex AU8830 (Vortex 2)  -----"; BREAK;
                DEFAULT:     AX = "-----------  Vortex ????? ------------"; BREAK;
            }
                    
            DWRITELN();
            // output vortex model
            DWRITE("Sound Card  = "); DWRITELN( VORTEXMODEL() );
            DWRITE("VendorID    = "); DWRITELNHEXWORD(aureal_config.vendorID);            
            DWRITE("DeviceID    = "); DWRITELNHEXWORD(aureal_config.deviceID);            
            DWRITE("SubVendorID = "); DWRITELNHEXWORD(aureal_config.subsystem_vendorID);  
            DWRITE("SubSystemID = "); DWRITELNHEXWORD(aureal_config.subsystemID);         
            DWRITE("RevisionID  = "); DWRITELNHEXWORD(aureal_config.revisionID);          
            DWRITE("PCI Bus     = "); AX = 0; AL = DSBYTE[#deviceH+1];      DWRITELNDECWORD();
            DWRITE("PCI Device  = "); AX = deviceH & 3;                     DWRITELNDECWORD();
            DWRITE("PCI Func    = "); AX = deviceH >> 3; AX &= 1Fh;         DWRITELNDECWORD();                        
            DWRITE("MemBaseAddr = "); EAX = aureal_config.memory_address;       DWRITELNHEXDWORD(); 
            DWRITE("IO Port 1   = "); EAX = aureal_config.IO_Port1; AL &= 0FEh; DWRITELNHEXDWORD(); 
            DWRITE("IO Port 2   = "); EAX = aureal_config.IO_Port2; AL &= 0FEh; DWRITELNHEXDWORD(); 
            DWRITE("Interrupt   = "); AX = 0; AL = aureal_config.IRQline;       DWRITELNDECWORD();

            $popA
            BP++; 
        }
    }

    DWRITE("---------------------------------------\nFound ");
    DWRITEDECWORD( BP );
    DWRITELN(" Vortex board(s)");
    AX = BP;
}
