/* * BIOS.CPP - Contains BIOS functions. * Copyright (C) 1998, 1999 Prashant TR * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * See the file COPYING.TR for more details. */ // ID for this file. #define _BIOS_CC_ #include "bios.h" int errflag = 0; FILE *fp; char *bios; char cmdline[20]; #define ENTRIES 6 typedef struct { char vendor[80]; char vendorname[80]; int vendorid; int idsize; } BIOSINFO; BIOSINFO vendor[ENTRIES] = { { "Award", "Award Software Inc.", 0 }, { "American Megatrends", "American Megatrends Inc.", 1 }, { "Phoenix", "Phoenix Technologies Ltd.", 2 }, { "Quadtel", "Quadtel", 3 }, { "Compaq", "Compaq", 4 }, { "Dell", "Dell", 5 }, }; // Write any string to the file and check for successfulness. void writestring(const char *string) { if (fprintf(fp, "%s", string) == EOF) { errflag = 2; checkerrors(); } } int run_module_cmdline(const char *cmdline, const char *pinfile, const char *file, const char *ucase_file) { FILE *fp1; unsigned long exitcode; if ((fp1 = fopen("cmdline.$$$", "wb")) == NULL) fprintf(stderr, "Error: Argument setup failed (%s)\n\r", ucase_file); else { fprintf(fp1, "%s\r\n", cmdline); fclose(fp1); unlink("temp.$$$"); exitcode = pinrun(pinfile, file); if (exitcode == -1) fprintf(stderr, "Error: Unable to spawn %s\r\n", ucase_file); } return (exitcode); } int sysinfo() { char output[256]; FILE *fp1; long vendorid, i, j; int exitcode; unsigned short ver; union REGS regs; struct SREGS segs; bios = (char *)MK_FP(0xf000, 0); // Create output file. if ((fp = fopen("bios.txt", "w")) == NULL) { errflag = 1; checkerrors(); } writestring("\nBIOS :\n"); // Initialize size field in the BIOS entries. for(i = 0; i < ENTRIES; i++) vendor[i].idsize = strlen(vendor[i].vendor); // Get BIOS information. vendorid = -1; for(i = 0; ((i < 65500) && (vendorid == -1)); i++) for(j = 0; ((j < 5) && (vendorid == -1)); j++) if (!strnicmp(&bios[i], vendor[j].vendor, vendor[j].idsize)) vendorid = j; sprintf(output, "\tBIOS Manufacturer : %s\n", (vendorid != -1) ? vendor[vendorid].vendorname : "(Unknown)"); writestring(output); // Get BIOS date. sprintf(output, "\tBIOS date : %c%c%c%c%c%c%c%c\n", bios[0xfff5], bios[0xfff6], bios[0xfff7], bios[0xfff8], bios[0xfff9], bios[0xfffa], bios[0xfffb], bios[0xfffc]); writestring(output); // Get Plug and Play BIOS information. // Spawn "pnp.exe", "dmi.exe" and "apm.exe". if (run_module_cmdline("pnp_version", "sysinfo.pin", "pnp.exe", "PNP.EXE") != -1) { unsigned long ptr; if ((fp1 = fopen("temp.$$$", "r")) == NULL) fprintf(stderr, "Error: Unable to get PNP BIOS " "information\r\n"); else { if (fscanf(fp1, "%c%lp", &ver, &ptr) != 2) fprintf(stderr, "Error: Unable to get " "PNP BIOS information\r\n"); } fclose(fp1); unlink("temp.$$$"); // Append information. sprintf(output, "\tHas PNP BIOS extensions : %s\n", ptr ? "Yes" : "No"); writestring(output); sprintf(output, "\tPlug and Play entry point : %lp\n", ptr); writestring(output); if (ptr) { sprintf(output, "\tPlug and Play version : %d.%d\n", (ver & 0xf0) >> 4, ver & 0xf); writestring(output); } } if (run_module_cmdline("dmi_version", "sysinfo.pin", "dmi.exe", "DMI.EXE") != -1) { unsigned char dmi_ver = 0; if ((fp1 = fopen("temp.$$$", "r")) == NULL) fprintf(stderr, "Error: Unable to get DMI BIOS " "information\r\n"); else { if (!fscanf(fp1, "%c", &dmi_ver)) fprintf(stderr, "Error: Unable to get DMI " "BIOS information\r\n"); fclose(fp1); unlink("temp.$$$"); // Append information. if (dmi_ver) { sprintf(output, "\tDMI BIOS version " " : %d.%d\n", (dmi_ver & 0xf0) >> 4, dmi_ver & 0xf); writestring(output); } } } // Get PCI BIOS Information. regs.x.ax = 0xb101; int86(0x1a, ®s, ®s); asm { MOV AX, 0B101H INT 1AH OR AH, AH JNZ label1 DB 66H, 81H, 0FAH // CMP EDX, 20494350 DD 20494350H JNZ label1 } if (!(regs.x.flags & 1)) {// && (regs.d.edx == 0x20494350)) { // Get PCI BIOS information. sprintf(output, "\tPCI BIOS version : %X.%02X\n", regs.h.bh, regs.h.bl); writestring(output); // Write entry point information. // printf("Protected mode entry point ... %lxh\n", regs.d.edi); // sprintf(output, "\tProtected Mode Entry Point : %lXh\n", regs.d.edi); // writestring(output); } else { label1: } // Get BIOS APM Information. if ((fp1 = fopen("cmdline.$$$", "wb")) == NULL) fprintf(stderr, "Error: Argument setup failed (APM.EXE)\n\r"); else { fprintf(fp1, "apm_version\r\n"); fclose(fp1); unlink("temp.$$$"); exitcode = pinrun("sysinfo.pin", "apm.exe"); if (exitcode == -1) fprintf(stderr, "Error: Unable to spawn APM.EXE\r\n"); else { if ((fp1 = fopen("temp.$$$", "r")) == NULL) fprintf(stderr, "Error: Unable to get BIOS APM " "information\r\n"); if (fp1 != NULL) { unsigned char apm_major = 0, apm_minor = 0; if (!fscanf(fp1, "%c%c", &apm_major, &apm_minor)) fprintf(stderr, "Error: Unable to get BIOS APM " "information\r\n"); fclose(fp1); unlink("temp.$$$"); // Append information. if (apm_major || apm_minor) { sprintf(output, "\tBIOS APM version : %d.%d\n", apm_major, apm_minor); writestring(output); } } } } // Get ROM table if present. regs.h.ah = 0xc0; int86x(0x15, ®s, ®s, &segs); if (!(regs.x.flags & 1)) { long unsigned offset, leng; unsigned char *ptr; sprintf(output, "\tROM BIOS Information pointer : %04X:%04X\n", segs.es, regs.x.bx); writestring(output); leng = *(unsigned short *)MK_FP(segs.es, regs.x.bx); if (leng -= 3) { unsigned id1, id2, id3; ptr = (unsigned char *)MK_FP(segs.es, regs.x.bx + 2); id1 = *ptr++; id2 = *ptr++; id3 = *ptr++; sprintf(output, "\tBIOS ID : %02X %02X %02X\n", id1, id2, id3); writestring(output); } // Write other information. Don't print. if (leng--) { writestring("\nBIOS FEATURES :\n\n"); sprintf(output, "\tSystem has dual bus : %s\n", (*ptr & 1) ? "Yes" : "No"); writestring(output); sprintf(output, "\tISA replaced by Microchannel : %s\n", (*ptr & 2) ? "Yes" : "No"); writestring(output); sprintf(output, "\tExtended BIOS area allocated : %s\n", (*ptr & 4) ? "Yes" : "No"); writestring(output); sprintf(output, "\tExternal event wait support : %s\n", (*ptr & 8) ? "Yes" : "No"); writestring(output); sprintf(output, "\tKeyboard intercept AH=4Fh : %s\n", (*ptr & 16) ? "Yes" : "No"); writestring(output); sprintf(output, "\tReal Time Clock installed : %s\n", (*ptr & 32) ? "Yes" : "No"); writestring(output); sprintf(output, "\tSecond 8259 PIC installed : %s\n", (*ptr & 64) ? "Yes" : "No"); writestring(output); sprintf(output, "\tDMA Ch-3 used by HDD BIOS : %s\n", (*ptr++ & 128) ? "Yes" : "No"); writestring(output); } if (leng --) { sprintf(output, "\tData streaming supported : %s\n", (*ptr & 2) ? "Yes" : "No"); writestring(output); sprintf(output, "\tNon-8042 KBD controller : %s\n", (*ptr & 4) ? "Yes" : "No"); writestring(output); sprintf(output, "\tINT 15h/AH = C8h supported : %s\n", (*ptr & 8) ? "Yes" : "No"); writestring(output); sprintf(output, "\tINT 15h/AH = C7h supported : %s\n", (*ptr & 16) ? "Yes" : "No"); writestring(output); sprintf(output, "\tINT 15h/AH = C6h supported : %s\n", (*ptr & 32) ? "Yes" : "No"); writestring(output); sprintf(output, "\tINT 16h/AH = 09h supported : %s\n", (*ptr++ & 64) ? "Yes" : "No"); writestring(output); } if (leng --) { sprintf(output, "\tSCSI suppored in IML : %s\n", (*ptr & 1) ? "Yes" : "No"); writestring(output); sprintf(output, "\tInitial Machine Load (IML) : %s\n", (*ptr & 2) ? "Yes" : "No"); writestring(output); sprintf(output, "\tInformation Panel Installed : %s\n", (*ptr & 4) ? "Yes" : "No"); writestring(output); sprintf(output, "\tSCSI subsystem supported : %s\n", (*ptr & 8) ? "Yes" : "No"); writestring(output); } } // For Award BIOS only. if (!vendorid) { writestring("\nSPECIAL BIOS INFORMATION :\n\n"); char string[] = "Award Modular BIOS v"; int len = strlen(string); for(i = 0; ((i < 65500) && (vendorid -1)); i++) if (!strnicmp(&bios[i], string, len)) break; if (i < 65500) { // We have found the BIOS make. sprintf(output, "\tBIOS Make : %s\n", &bios[i]); writestring(output); } // Check for special BIOS information. strcpy(string, "ATC-"); len = 4; for(i = 0; ((i < 65500) && (vendorid -1)); i++) if (!strncmp(&bios[i], string, len)) break; if (i < 65500) { // We have found the BIOS make. sprintf(output, "\tAdditional BIOS information : %s\n", &bios[i]); writestring(output); // Get unique ID. for(i = 0; i < 65500; i++) if ((isdigit(bios[i])) && (isdigit(bios[i + 1])) && (bios[i + 2] == '/') && (isdigit(bios[i + 3])) && (isdigit(bios[i + 4])) && (bios[i + 5] == '/') && (isdigit(bios[i + 6])) && (isdigit(bios[i + 7])) && (bios[i + 8] == '-') && (bios[i + 9] == 'i') && (bios[i + 15] == '-')) break; if (i < 65500) { sprintf(output, "\tUnique ID : %s\n", &bios[i]); writestring(output); } } } fclose(fp); return 0; } void open_stderr() { fclose(stdout); fclose(&_streams[2]); if (fopen("nul", "wb") == NULL) exit(0x7f); if (fopen("nul", "wb") == NULL) exit(0x7f); if ((stderr = fopen("errors.$$$", "ab")) == NULL) exit(0x7f); } void get_cmdline() { if ((fp = fopen("cmdline.$$$", "rb")) == NULL) exit (0x7f); if (fscanf(fp, "%s", cmdline) != 1) { fclose(fp); exit (0x7f); } fclose(fp); unlink("cmdline.$$$"); } #pragma argsused // The main function. int main(int argc, char **argv) { open_stderr(); get_cmdline(); if (!strcmp(cmdline, "sysinfo")) return (sysinfo()); return 0; }