#include    <stdio.h>
#include    <string.h>
#include    <stdlib.h>
#include    <conio.h>
#include    <doscalls.h>


//  *********************
//  STATIC FUNCTIONS ONLY
//  *********************

typedef unsigned char   UCHAR;
typedef unsigned short  USHORT;
typedef unsigned int    UINT;
typedef unsigned long   ULONG;
typedef unsigned long   RC;
typedef char            CHAR;
typedef char            BYTE;
typedef short           SHORT;
typedef int             INT;
typedef long            LONG;
typedef UCHAR near    *PUCHAR;
typedef UCHAR far    *FPUCHAR;
typedef USHORT near   *PUSHORT;
typedef ULONG near    *PULONG;
typedef char near     *PCHAR;
typedef short near    *PSHORT;
typedef long near     *PLONG;
typedef void near     *POINTER;
typedef POINTER near *PPOINTER;
typedef far           FAR;
typedef far             *FARPOINTER;
typedef FARPOINTER near *PFARPOINTER;
typedef FARPOINTER far *FPFARPOINTER;
#define VOID        void
#define TRUE    (1)
#define FALSE   (0)

#include "oem.h"

static USHORT oem_open (VOID);
static USHORT oem_ioctl (UCHAR *buffer, UCHAR *param,
                       unsigned funct, unsigned cat);
static USHORT oem_screen_open (VOID);
static USHORT oem_screen_ioctl (UCHAR *buffer, UCHAR *param,
                                unsigned funct, unsigned cat);
static FILE  *Oem_fd;
static FILE  *Screen_fd;

VOID oem_info (OEM *oem)
{
 struct oem0
 {
    UCHAR oem_name[20];
    UCHAR oem_revision[10];
    UCHAR spare[40];
 } oem0;
/*
 struct oem1
 {
    UCHAR oem_man_name[20];
    UCHAR oem_model[10];
    UCHAR oem_rom_revision[10];
    UCHAR spare[40];
 } oem1;
*/
 struct oem8
 {
    USHORT oem_adapter;
    USHORT oem_chip_type;
    ULONG  oem_ram_size;
    UCHAR spare[40];
 } oem8;
 struct screenB
 {
    ULONG oem_screen_packetlen;
    ULONG oem_screen_physical;
    ULONG oem_screen_aperturesize;
    ULONG oem_screen_linearaddr;
    ULONG oem_screen_linearflags;
 } screenB1;
 UCHAR unknown_chip_type [20];
 int    count;

        if (!oem_open ())
            return;
        if (!oem_screen_open ())
            return;

        oem_ioctl ((UCHAR *)&oem0, NULL, 0, 0x80);
        sprintf (oem->oem_name, "%s", oem0.oem_name);

/*
        oem_ioctl ((UCHAR *)&oem1, NULL, 1, 0x80);
        printf ("OEM Manufacturer Name %20.20s Model %10.10s Rev. %10.10s\n",
                  oem1.oem_man_name, oem1.oem_model, oem1.oem_rom_revision);
*/

        oem_ioctl ((UCHAR *)&oem8, NULL, 8, 0x80);
        sprintf (unknown_chip_type, "Unknown (%d)", oem8.oem_chip_type);
        switch (oem8.oem_adapter)
        {
            case 0 :
                sprintf (oem->oem_hw,
                     "VGA Adapter Indeterminate chip type %d",
                     oem8.oem_chip_type);
                break;

            case 1 :
                sprintf (oem->oem_hw, "Headland Technology Inc. chip type %s",
                     (oem8.oem_chip_type == 1) ? "HT205" :
                     (oem8.oem_chip_type == 2) ? "HT208" :
                     (oem8.oem_chip_type == 3) ? "HT209" : unknown_chip_type);
                break;

            case 2 :
                sprintf (oem->oem_hw, "Trident MicroSystems chip type %s",
                     (oem8.oem_chip_type == 1) ? "8800" :
                     (oem8.oem_chip_type == 2) ? "8900" : unknown_chip_type);
                break;

            case 3 :
                sprintf (oem->oem_hw, "Tseng Labs chip type %s",
                     (oem8.oem_chip_type == 1) ? "ET3000" :
                     (oem8.oem_chip_type == 2) ? "ET4000" :
                     (oem8.oem_chip_type == 3) ? "ET4000W32" :
                     (oem8.oem_chip_type == 4) ? "ET4000W32I" :
                     (oem8.oem_chip_type == 5) ? "ET4000W32IB" :
                     (oem8.oem_chip_type == 6) ? "ET4000W32IC" :
                     (oem8.oem_chip_type == 7) ? "ET4000W32PA" :
                     (oem8.oem_chip_type == 8) ? "ET4000W32PB" :
                     (oem8.oem_chip_type == 9) ? "ET4000W32PC" :
                     (oem8.oem_chip_type ==10) ? "ET4000W32ID" :
                     (oem8.oem_chip_type ==11) ? "ET4000W32PD" :
                     (oem8.oem_chip_type ==12) ? "ET4000W32PX" :
                                                  unknown_chip_type);
                break;

            case 4 :
                sprintf (oem->oem_hw, "Western Digital chip type %s",
                     (oem8.oem_chip_type == 1) ? "PVGA1A" :
                     (oem8.oem_chip_type == 2) ? "WD9000" :
                     (oem8.oem_chip_type == 3) ? "WD9011" :
                     (oem8.oem_chip_type == 4) ? "WD9030" :
                     (oem8.oem_chip_type == 5) ? "WD9026" :
                     (oem8.oem_chip_type == 6) ? "WD9027" :
                     (oem8.oem_chip_type == 7) ? "WD9031" :
                     (oem8.oem_chip_type == 8) ? "WD9024" :
                     (oem8.oem_chip_type == 9) ? "WD9033" : unknown_chip_type);
                break;

            case 5 :
                sprintf (oem->oem_hw, "ATI Technologies chip type %s",
                     (oem8.oem_chip_type == 1) ? "VGAWONDER" :
                     (oem8.oem_chip_type == 2) ? "VGAWONDER+XT" :
                     (oem8.oem_chip_type == 3) ? "MACH8 Graphics Ultra" :
                     (oem8.oem_chip_type == 4) ? "MACH32 Graphics Ultra Pro" :
                     (oem8.oem_chip_type == 5) ? "MACH64" :
                     (oem8.oem_chip_type == 6) ? "MACH64CT" :
                                                          unknown_chip_type);
                break;

            case 6 :
                sprintf (oem->oem_hw, "IBM Technologies chip type");
                break;

            case 7 :
                sprintf (oem->oem_hw, "Cirrus Logic chip type %s",
                     (oem8.oem_chip_type == 1) ? "5420" :
                     (oem8.oem_chip_type == 2) ? "5422" :
                     (oem8.oem_chip_type == 3) ? "5424" :
                     (oem8.oem_chip_type == 4) ? "5426" :
                     (oem8.oem_chip_type == 5) ? "5428" :
                     (oem8.oem_chip_type == 6) ? "5429" :
                     (oem8.oem_chip_type == 7) ? "543x" :
                     (oem8.oem_chip_type == 8) ? "5434" :
                     (oem8.oem_chip_type == 9) ? "6235" :
                                                          unknown_chip_type);
                break;

            case 8 :
                sprintf (oem->oem_hw, "S3 chip type %s",
                     (oem8.oem_chip_type == 1) ? "86C805" :
                     (oem8.oem_chip_type == 2) ? "86C928" :
                     (oem8.oem_chip_type == 3) ? "86C911" :
                     (oem8.oem_chip_type == 4) ? "86C864" :
                     (oem8.oem_chip_type == 5) ? "86C964" :
                     (oem8.oem_chip_type == 6) ? "86C868" :
                     (oem8.oem_chip_type == 7) ? "86C968" :
                     (oem8.oem_chip_type == 8) ? "86C732" :
                     (oem8.oem_chip_type == 9) ? "86C764" :
                     (oem8.oem_chip_type == 10) ? "86C765" :
                     (oem8.oem_chip_type == 11) ? "Aurora64V" :
                     (oem8.oem_chip_type == 12) ? "ViRGE" :
                     (oem8.oem_chip_type == 13) ? "ViRGE/vX" :
                     (oem8.oem_chip_type == 14) ? "Trio64UV+" :
                     (oem8.oem_chip_type == 15) ? "Trio64V+" :
                     (oem8.oem_chip_type == 16) ? "86C924" :
                     (oem8.oem_chip_type == 17) ? "86C866" :
                     (oem8.oem_chip_type == 18) ? "86C928 PCI" :
                                                          unknown_chip_type);
                break;

            case 9 :
                sprintf (oem->oem_hw, "Chips & Technology chip type %x",
                     oem8.oem_chip_type);
                break;

            case 10 :
                sprintf (oem->oem_hw, "Weitek chip type %s",
                     (oem8.oem_chip_type == 1) ? "P9000" :
                     (oem8.oem_chip_type == 2) ? "W5186" :
                     (oem8.oem_chip_type == 3) ? "W5286" :
                     (oem8.oem_chip_type == 4) ? "P9100" : unknown_chip_type);
                break;

            case 11 :
                sprintf (oem->oem_hw, "Number 9 chip type %x",
                     oem8.oem_chip_type);
                break;

            case 12 :
                sprintf (oem->oem_hw, "Generic PCI SVGA chip type %x",
                     oem8.oem_chip_type);
                break;

            case 13 :
                sprintf (oem->oem_hw, "OAK Technologies chip type %x",
                     oem8.oem_chip_type);
                break;

            case 14 :
                sprintf (oem->oem_hw, "Matrox chip type %x",
                     oem8.oem_chip_type);
                break;

            case 15 :
                sprintf (oem->oem_hw, "Brooktree chip type %x",
                     oem8.oem_chip_type);
                break;

            case 16 :
                sprintf (oem->oem_hw, "NVidia chip type %x",
                     oem8.oem_chip_type);
                break;

            case 17 :
                sprintf (oem->oem_hw, "Alliance chip type %x",
                     oem8.oem_chip_type);
                break;

            case 18 :
                sprintf (oem->oem_hw, "Avance chip type %x",
                     oem8.oem_chip_type);
                break;

            case 19 :
                sprintf (oem->oem_hw, "Mediavision chip type %x",
                     oem8.oem_chip_type);
                break;

            case 20 :
                sprintf (oem->oem_hw, "Ark Logic chip type %x",
                     oem8.oem_chip_type);
                break;

            case 21 :
                sprintf (oem->oem_hw, "Radius chip type %x",
                     oem8.oem_chip_type);
                break;

            case 22 :
                sprintf (oem->oem_hw, "3D Labs chip type %x",
                     oem8.oem_chip_type);
                break;

            case 23 :
                sprintf (oem->oem_hw, "NCR chip type %x",
                     oem8.oem_chip_type);
                break;

            case 24 :
                sprintf (oem->oem_hw, "IIT chip type %x",
                     oem8.oem_chip_type);
                break;

            case 25 :
                sprintf (oem->oem_hw, "Appian chip type %x",
                     oem8.oem_chip_type);
                break;

            case 26 :
                sprintf (oem->oem_hw, "Sierra chip type %x",
                     oem8.oem_chip_type);
                break;

            case 27 :
                sprintf (oem->oem_hw, "Cornerstone chip type %x",
                     oem8.oem_chip_type);
                break;

            case 28 :
                sprintf (oem->oem_hw, "Digital chip type %x",
                     oem8.oem_chip_type);
                break;

            case 29 :
                sprintf (oem->oem_hw, "Compaq chip type %x",
                     oem8.oem_chip_type);
                break;

            case 30 :
                sprintf (oem->oem_hw, "Infotronic chip type %x",
                     oem8.oem_chip_type);
                break;

            case 31 :
                sprintf (oem->oem_hw, "Opti chip type %x",
                     oem8.oem_chip_type);
                break;

            case 32 :
                sprintf (oem->oem_hw, "NULL chip type %x",
                     oem8.oem_chip_type);
                break;
            default :
                sprintf (oem->oem_hw, "Unknown adapter %x chip type %x",
                     oem8.oem_adapter,
                     oem8.oem_chip_type);
                break;

        }
        oem->oem_ram = oem8.oem_ram_size;


        // Get screen information
        screenB1.oem_screen_packetlen = sizeof (screenB1);
        screenB1.oem_screen_physical = 0xA0000;
        screenB1.oem_screen_aperturesize = 0x10000;
        screenB1.oem_screen_linearaddr = 0;
        screenB1.oem_screen_linearflags = 0x410;

        oem_screen_ioctl (NULL, (UCHAR *)&screenB1, 0xB, 0x80);

        oem->oem_screen_packetlen        = screenB1.oem_screen_packetlen;
        oem->oem_screen_physical         = screenB1.oem_screen_physical;
        oem->oem_screen_aperturesize     = screenB1.oem_screen_aperturesize;
        oem->oem_screen_linearaddr       = screenB1.oem_screen_linearaddr;
        oem->oem_screen_linearflags      = screenB1.oem_screen_linearflags;
}

static USHORT oem_ioctl (UCHAR *buffer, UCHAR *param,
                       unsigned funct, unsigned cat)
{
        if (!Oem_fd)
            return TRUE;
        return DOSDEVIOCTL (buffer, NULL, funct, cat, Oem_fd);
}


static USHORT oem_screen_ioctl (UCHAR *buffer, UCHAR *param,
                                unsigned funct, unsigned cat)
{
        if (!Screen_fd)
            return TRUE;
        return DOSDEVIOCTL (buffer, param, funct, cat, Screen_fd);
}


static USHORT oem_open ()
{
 USHORT result, x, mode;

        mode  = 0x42;       // shared open read/write
        mode |= 0x80;       // handle inherited
        x = DOSOPEN ("OEMHLP$", &Oem_fd, &result, 0L, 0, 1, mode, 0L);
        if (x != 0)
        {
                Oem_fd = NULL;
                return FALSE;
        }
        return TRUE;
}


static USHORT oem_screen_open ()
{
 USHORT result, x, mode;

        mode  = 0x42;       // shared open read/write
        mode |= 0x80;       // handle inherited
        x = DOSOPEN ("SCREEN$", &Screen_fd, &result, 0L, 0, 1, mode, 0L);
        if (x != 0)
        {
                Screen_fd = NULL;
                return FALSE;
        }
        return TRUE;
}

