/* 'whoisit.c' K.Saito Sep.2.1989 Editor K.Kono Mar.7.1996 reports system configuration and BIOS data */ #include #include #define SYSTEM_SERVICE 0x15 #define SYSTEM_CONFIG 0xc0 union REGS inregs, outregs; struct SREGS segregs; int inspection(unsigned char far *ptr); int understandable(unsigned char far *ptr); int disp_date(); int main(void) { unsigned char far *ptr; /* HEXバイト表示のため符号なし */ unsigned char far *model_byte = (char far *) 0xf000ffel; /* farポインタによって特定アドレスを指定 */ inregs.h.ah = SYSTEM_CONFIG; int86x(SYSTEM_SERVICE, &inregs, &outregs, &segregs); /* BIOSコール */ if(outregs.x.cflag) switch(outregs.h.ah){ case 0x80: switch(*model_byte){ case 0xff: printf("\nIBM PC"); disp_date(); break; case 0xfd: printf("\nIBM PCjr"); disp_date(); break; default: printf("\nUNKNOWN"); } break; case 0x86: switch(*model_byte){ case 0xfe: printf("\nIBM PC XT"); disp_date(); break; case 0xfc: printf("\nIBM PC AT"); disp_date(); break; default: printf("\nUNKNOWN"); } break; default: printf("\nUNKNOWN !"); } else if(outregs.h.ah) printf("\nUNKNOWN !"); else{ ptr = (char far *)((unsigned long)segregs.es << 16 | (unsigned)outregs.x.bx); /* es, bxを連結して32ビットのfarアドレスを生成 */ inspection(ptr); printf("\nSystem descriptors [%p]", ptr); printf("\n Model: %02Xh", *(ptr+2)); printf("\n Submodel: %02Xh", *(ptr+3)); printf("\n BIOS revision: %02Xh", *(ptr+4)); printf("\n Feature information: %02Xh", *(ptr+5)); understandable(ptr+5); disp_date(); } printf("\n\n"); return 0; } int inspection(ptr) unsigned char far *ptr; { printf("\nProduct: "); /* 機種を判定する関数 */ switch(*(ptr+2)){ case 0xfc: switch(*(ptr+3)){ case 0: case 1: printf("PC AT"); break; case 2: printf("PC XT 286"); break; case 4: printf("PS/2 Model 50"); break; case 5: printf("PS/2 Model 60"); break; case 9: printf("PS/2 Model 30 286"); break; default: printf("May be PC AT compatible"); } break; case 0xfb: printf("PC XT"); break; case 0xfa: printf("PS/2 Model 30"); break; case 0xf9: printf("PC Convertible"); break; case 0xf8: printf("PS/2 Model 80"); break; default: printf("May be PC or PS/2 Compatible"); } return 0; } int understandable(ptr) unsigned char far *ptr; /* 各機種ごとに違う特徴を判定して表示する関数(85年以降) */ { if(*ptr & 0x80) printf("\n\tFixed disk BIOS uses DMA ch3"); else printf("\n\tDMA channel 3 used by fixed disk"); printf("\n\t2nd interrupt chip "); if(*ptr & 0x40) printf("present"); else printf("not present"); printf("\n\tReal time clock "); if(*ptr & 0x20) printf("present"); else printf("not present"); printf("\n\tKeyboard intercept sequence "); if(*ptr & 0x10) printf("called in keyboard interrupt"); else printf("not called"); printf("\n\tWait for external event "); if(*ptr & 0x8) printf("supported"); else printf("not supported"); printf("\n\tExtened BIOS data area is "); if(*ptr & 0x4) printf("allocated"); else printf("not allocated"); if(*ptr & 0x2) printf("\n\tMicro channel"); else printf("\n\tPC type I/O channel"); return 0; } int disp_date() /* BIOS日付を表示する関数 */ { int n; unsigned char far *bios_date = (char far *) 0xf000fff5l; printf("\nBIOS dated: "); for(n=0;n<8;n++){ printf("%c", *bios_date); *bios_date++; } return 0; }