hottobar

C program to read the CMOS memory

Sep 28th, 2014
490
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.46 KB | None | 0 0
  1. /*
  2. CMOS memory reader for DOS (tested on a IBM PS/1 model 2011, Intel 80286@10MHz)
  3. Save as cmos.c and compile with
  4.  tcc -1 cmos.c
  5. You need TCC and TASM installed.
  6. */
  7. #include <stdio.h>
  8. #define CMOS_SIZE 64
  9.  
  10. /*
  11. This function reads a value from the CMOS, preserving the passed NMI bit value.
  12. To read the CMOS this function disables NMIs. It's responsibility of the caller to inform this function
  13. about the current state of the NMI bit.
  14. So to read CMOS byte 0Fh with NMI restored to enabled call read_cmos(0x0F). Call read_cmos(0x8F) otherwise.
  15.  
  16. The asm procedure was taken from the BIOS of a IBM PS/1 model 2011.
  17. */
  18. unsigned char read_cmos(unsigned char _addr)
  19. {
  20.     unsigned char value;
  21.     asm {
  22.     mov al, _addr
  23.     pushf           /* save the CPU flags */   
  24.     rol     al, 1       /* rotate 8-bit AL left once (AL[0] = AL[7]) */
  25.     stc         /* CF = 1 */
  26.     rcr     al, 1       /* save the original value of _addr[7] (the NMI bit) in CF.
  27.                 rotate 9-bits (CF, AL) right once. now AL[7]=1 (NMI disabled) and CF=AL[0] */
  28.     cli         /* IF = 0 (disable interrupts) */
  29.     out     70h, al     /* inform the CMOS about the memory register we want to read */
  30.     jmp     short $+2   /* delay */
  31.     in      al, 71h     /* read the CMOS register value and put it in AL */
  32.     push    ax      /* save AX */
  33.     mov     al, 1Eh     /* AL = 11110b (0Fh shifted left by 1) */
  34.     rcr     al, 1       /* reset the NMI bit to its original value. rotate 9-bits (CF, AL) right once */
  35.     out     70h, al     /* CMOS reg = AL (it can be 8Fh or 0Fh) */
  36.     jmp     short $+2   /* delay */
  37.     in      al, 71h     /* bogus CMOS read to keep the chip happy */
  38.     pop     ax      /* restore AX */
  39.     popf            /* restore CPU flags */
  40.     mov value, al   /* return the read CMOS value for index _addr */
  41.     }
  42.     /*
  43.     The "mov value, al" is redundant, because to translate "return value;" the compiler will add
  44.     "mov al, [bp+var_1]" at the end anyway (AL is the register where the function return value should be).
  45.     But I will leave the instruction there, with the associated "return value;", just for clarity.
  46.     */
  47.     return value;
  48. }
  49.  
  50. int main()
  51. {
  52.     unsigned char p, cmos[CMOS_SIZE];
  53.     FILE *outf;
  54.    
  55.     /* read the CMOS in its entirety */
  56.     for(p=0; p<CMOS_SIZE; p++) {
  57.         cmos[p] = read_cmos(p);
  58.     }
  59.    
  60.     /* write the CMOS data to screen and file */
  61.     outf = fopen("cmos.txt","w");
  62.     if(outf == NULL) {
  63.         printf("error opening file\n");
  64.         return 1;
  65.     }
  66.     for(p=0; p<CMOS_SIZE; p++) {
  67.         printf("[%2X=%2X] ", p, cmos[p]);
  68.         fprintf(outf, "%2X = %2X\n", p, cmos[p]);
  69.     }
  70.     fclose(outf);
  71.    
  72.     return 0;
  73. }
Advertisement
Add Comment
Please, Sign In to add comment