Link to home
Start Free TrialLog in
Avatar of hank1
hank1

asked on

cmos access

We use pcs running NT4 to control industrial machines and it is important
that any pc power management options be disabled.

Before shipping a perl script checks the pc configuration.  Is there
anyway to read the CMOS?  Presently the technicians are
instructed to incept the boot and check these power mgnt
options via the bios setup utility.

Thanks for any ideas.
ASKER CERTIFIED SOLUTION
Avatar of jhance
jhance

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of hank1
hank1

ASKER

Is there such a dd?
You could create a DOS based boot floppy disk and write a DOS based (remember them) application to update the BIOS whilst under DOS.

You would have to locate the address and format of the APM areas of the BIOS as I do not believe there is any standard for these values and it may well vary from BIOS to BIOS.

You will alos probably have to recalculate the BIOS checksum.

If it is of any interest I have attached some code snippets from a (very) old program I wrote to disable floppy access to PCs at work. If any of the code is helpful you are welcome it. Just be aware that this code was set up to talk to the particular BIOS in our machines at the time (486DX2 DECs from memory)


#include      <conio.h>
#include <stdio.h>
#include "rtc.h"
#include <process.h>

void main (void) {
int x,y,Loc,Data;

  printf ("\n%33s\n\n  ", "CMOS RAM Dump");
  for (x = 0; x < 0x10; x++)
    printf (" %2X", x);
  puts ("\n--------------------------------------------------");
  for (x = 0; x < 4; x++) {
    printf ("%X ", x);
    for (y = 0; y < 0x10; y++) {
      Loc = (x << 4) + y;
      Data = ReadCMOS (Loc);
      printf (" %02X", Data);
    }
    printf ("\n");
  }
  printf ("\nOld value at location 10h = %02X\n", ReadCMOS (0x10));
  WriteCMOS (0x10,0x00);
  NewCMOSChecksum ();
  printf ("\nNew value at location 10h = %02X\n", ReadCMOS (0x10));
  printf ("\n\n%33s\n\n  ", "CMOS RAM Dump");
  for (x = 0; x < 0x10; x++)
    printf (" %2X", x);
  puts ("\n--------------------------------------------------");
  for (x = 0; x < 4; x++) {
    printf ("%X ", x);
    for (y = 0; y < 0x10; y++) {
      Loc = (x << 4) + y;
      Data = ReadCMOS (Loc);
      printf (" %02X", Data);
    }
    printf ("\n");
  }

  printf("System will now reboot to remove floppy disks from equipment\n");
  printf("Press any key to reboot ...........\n");
  getch();
  execl("WARMBOOT","WARMBOOT");
}

#include      "global.h"
#include       <stdio.h>
#include       <dos.h>
#include       "rtc.h"

/* Loop until "Update in Progress" bit is clear */
static void WaitForUpdate (void) {
    while (ReadCMOS (SRA) & UIP)
      ;
}

/* Read Value from CMOS RAM */
int ReadCMOS (int Addr) {
    int ch;
    asm pushf                           /* save interrupt flag */
    disable ();
    if (Addr < SRA) WaitForUpdate ();
    outportb (CMOS_Control, Addr);
    ch = inportb (CMOS_Data);
    asm popf                         /* restore interrupt flag */
    return ch;
} /* ReadCMOS */

/* Write Value to CMOS RAM */
void WriteCMOS (char Addr, char Value) {
    asm pushf                           /* save interrupt flag */
    disable ();
    if (Addr < SRA) WaitForUpdate ();
    outportb (CMOS_Control, Addr);
    outportb (CMOS_Data, Value);
    asm popf                         /* restore interrupt flag */
} /* WriteCMOS */

/* Compute and store new CMOS checksum */
void NewCMOSChecksum (void) {
    int Loc, CheckSum = 0;
    for (Loc = 0x10; Loc < 0x2E; Loc++)
      CheckSum += ReadCMOS (Loc);
    WriteCMOS (0x2E, (CheckSum >> 8));
    WriteCMOS (0x2F, (CheckSum & 0xFF));
}

/* RTC.H -- Symbols and function prototypes for RTCHDW.C */

#define PIC1data 0x20                   /* PIC 1 data register */
#define PIC1ctrl 0x21                /* PIC 1 control register */
#define PIC2data 0xa0                   /* PIC 2 data register */
#define PIC2ctrl 0xa1                /* PIC 2 control register */
#define EOI  0x20                  /* "End of Interrupt" value */
#define ALARMINT 0x4A           /* User Alarm Interrupt number */
#define RTCINT 0x70                           /* RTC interrupt */
#define CMOS_Control 0x70             /* CMOS RAM control port */
#define CMOS_Data 0x71                   /* CMOS RAM data port */
#define SRA 0x0a                          /* Status Register A */
#define SRB 0x0b                          /* Status Register B */
#define SRC 0x0c                          /* Status Register C */
#define SRD 0x0d                          /* Status Register D */

/* Status Register A flag masks */
#define UIP 0x80                         /* Update in Progress */

/* Status Register B flag masks */
#define SET     0x80                       /* Halt update flag */
#define PIE     0x40              /* Periodic Interrupt Enable */
#define AIE     0x20                 /* Alarm Interrupt Enable */
#define UIE     0x10          /* Update-ended Interrupt Enable */
#define SQWE    0x08                     /* Square Wave Enable */
#define DM      0x04                              /* Data Mode */
#define AMPM    0x02                           /* 24/12 Switch */
#define DSE     0x01                /* Daylight Savings Enable */

/* Status Register C flag masks */
#define IRQF    0x80                      /* Interrupt Request */
#define PF      0x40                     /* Periodic Interrupt */
#define AF      0x20                        /* Alarm Interrupt */
#define UF      0x10                 /* Update-ended Interrupt */

/* Status Register D flag masks */
#define VRT     0x80                       /* Valid RAM & Time */

/* Time structure used by SetAlarmInt */
struct RTCTIME {
    unsigned int Hour;
    unsigned int Min;
    unsigned int Sec;
    unsigned int Daylight;
};

int ReadCMOS (int Addr);
void WriteCMOS (char Loc, char Data);
void NewCMOSChecksum (void);
int SetPeriodicInt (int Freq, void far (*isr)());
int SetUpdateInt (void far (*isr)());
int SetAlarmInt (struct RTCTIME *Time, void far (*isr)());
void EnableRTCint (int Which);
void DisableRTCint (int Which);
void ResetRTCint (int Which);
void TimerOn (void);
void TimerOff (void);


Cheers - Gavin
Avatar of hank1

ASKER

looks like you've been there.... let me digest this.
Thanks.
Avatar of hank1

ASKER

Could find no driver and the mfg do not support this.  Can't be done like you said.  Thanks everyone.