In order to read the content of the CMOS memory of my IBM PS/1 model 2011, I wrote the following C program.
It compiles with Turbo C and it needs TASM as well.
The content of the CMOS memory of my PS/1 can be found here.
You can download a precompiled version of the program here.
Pastebin of the following program
#include <stdio.h> #define CMOS_SIZE 64 /* This function reads a value from the CMOS, preserving the passed NMI bit value. To read the CMOS this function disables NMIs. It's responsibility of the caller to inform this function about the current state of the NMI bit. So to read CMOS byte 0Fh with NMI restored to enabled call read_cmos(0x0F). Call read_cmos(0x8F) otherwise. The asm procedure was taken from the BIOS of a IBM PS/1 model 2011. */ unsigned char read_cmos(unsigned char _addr) { unsigned char value; asm { mov al, _addr pushf /* save the CPU flags */ rol al, 1 /* rotate 8-bit AL left once (AL[0] = AL[7]) */ stc /* CF = 1 */ rcr al, 1 /* save the original value of _addr[7] (the NMI bit) in CF. rotate 9-bits (CF, AL) right once. now AL[7]=1 (NMI disabled) and CF=AL[0] */ cli /* IF = 0 (disable interrupts) */ out 70h, al /* inform the CMOS about the memory register we want to read */ jmp short $+2 /* delay */ in al, 71h /* read the CMOS register value and put it in AL */ push ax /* save AX */ mov al, 1Eh /* AL = 11110b (0Fh shifted left by 1) */ rcr al, 1 /* reset the NMI bit to its original value. rotate 9-bits (CF, AL) right once */ out 70h, al /* CMOS reg = AL (it can be 8Fh or 0Fh) */ jmp short $+2 /* delay */ in al, 71h /* bogus CMOS read to keep the chip happy */ pop ax /* restore AX */ popf /* restore CPU flags */ mov value, al /* return the read CMOS value for index _addr */ } /* The "mov value, al" is redundant, because to translate "return value;" the compiler will add "mov al, [bp+var_1]" at the end anyway (AL is the register where the function return value should be). But I will leave the instruction there, with the associated "return value;", just for clarity. */ return value; } int main() { unsigned char p, cmos[CMOS_SIZE]; FILE *outf; /* read the CMOS in its entirety */ for(p=0; p<CMOS_SIZE; p++) { cmos[p] = read_cmos(p); } /* write the CMOS data to screen and file */ outf = fopen("cmos.txt","w"); if(outf == NULL) { printf("error opening file\n"); return 1; } for(p=0; p<CMOS_SIZE; p++) { printf("[%2X=%2X] ", p, cmos[p]); fprintf(outf, "%2X = %2X\n", p, cmos[p]); } fclose(outf); return 0; }
Advertisements