Reading / writing cmos bios settings
Reading / writing cmos bios settings
This may be a strange / impossible / downright foolish thing to ask, but...
Is it possible to read and write your PC's bios settings from PB? I'd really like to be able to set my PC to wake up at a particular time, and I can only do that from the BIOS screen. But the wakeup time must be stored in the CMOS ram somewhere, and if that can be accessed, rummaged through and poked from PB, it would make things much easier. I'm not taking about writing to the BIOS memory itself, that would just be asking for a disaster, but the CMOS ram where the settings are stored.
A quick look for things like 'cmos poke' on google revealed the ancients had been doing it from MS DOS, in C and assembly, but looking that stuff made my head hurt! Has anyone got any idea how to do it?
Cheers,
Paul
Is it possible to read and write your PC's bios settings from PB? I'd really like to be able to set my PC to wake up at a particular time, and I can only do that from the BIOS screen. But the wakeup time must be stored in the CMOS ram somewhere, and if that can be accessed, rummaged through and poked from PB, it would make things much easier. I'm not taking about writing to the BIOS memory itself, that would just be asking for a disaster, but the CMOS ram where the settings are stored.
A quick look for things like 'cmos poke' on google revealed the ancients had been doing it from MS DOS, in C and assembly, but looking that stuff made my head hurt! Has anyone got any idea how to do it?
Cheers,
Paul
-
- User
- Posts: 48
- Joined: Tue Oct 07, 2003 3:10 pm
Paulr,
the CMOS chip is accessed at I/O port &h70 and &h71.
&h70 (hex 70) is the address of the CMOS register to read/write.
&h71 is where you read it from/write it to.
Whether you have access to these ports depends on your OS, Win98 does it with no problems, XP and others will need a work around (some sort of device driver from elsewhere that enables access to the hardware ports).
When accessing port &h70 beware that the MSB must not be altered. It does other things not related to the CMOS.
e.g.
To enable the alarm interrupt..
Use similar operations to set the alarm time:
You may also need to set/clear Register 12 bit 5 to control if the alarm causes an IRQ or not.
the CMOS chip is accessed at I/O port &h70 and &h71.
&h70 (hex 70) is the address of the CMOS register to read/write.
&h71 is where you read it from/write it to.
Whether you have access to these ports depends on your OS, Win98 does it with no problems, XP and others will need a work around (some sort of device driver from elsewhere that enables access to the hardware ports).
When accessing port &h70 beware that the MSB must not be altered. It does other things not related to the CMOS.
e.g.
To enable the alarm interrupt..
Code: Select all
!in al,&h70 ;get current address register
!and al,128 ;preserve top bit
!or al,11 ;CMOS status register 11 contains alarm bit
!out &h70,al ;status register is now addressable at &h71
!in al,&71 ;get the current contents of register 11
!or al,32 ;set the alarm enable bit (bit 5)
!out &h71,al ;write back to register.
Code: Select all
Register What it
number does
1 Alarm Seconds
3 Alarm Minute
5 Alarm Hour
11 Status register B containing alarm enable bit
12 Status register C containing alarm IRQ bit (bit5)
Thanks Roadrunner, that's just what I need to do, but I'm running XP I'm afraid. Can you tell me where I can find the kind of device driver you mentioned?
I found a dll at http://www.torry.net/portaccess.htm that seems to do what I need, but whenever I call it from PB it crashes. It might be to do with the way I'm calling it. Details below...
Here's part of the readme:
I found a dll at http://www.torry.net/portaccess.htm that seems to do what I need, but whenever I call it from PB it crashes. It might be to do with the way I'm calling it. Details below...
Here's part of the readme:
And here's my program:The Functions DLL DirectPort32.dll:
*********************************
procedure DoneDLL; stdcall; index 7; - Frees the memory used DLL (WITHOUT FALL AT TERMINATION !!!)
procedure ReadPortByte(Port:Word;var ByteResult:Byte); stdcall; index 1;
accordingly reads byte from port
procedure ReadPortWord(Port:Word;var WordResult:Word); stdcall; index 2;
accordingly reads word from port
procedure ReadPortDWord(Port:Word;var DWordResult:LongWord); stdcall; index 3;
accordingly reads the double word from port, below functions all this deal write.
procedure WritePortByte(Port:Word;ByteValue:Byte); stdcall; index 4;
procedure WritePortWord(Port:Word;WordValue:Word); stdcall; index 5;
procedure WritePortDWord(Port:Word;DWordValue:LongWord); stdcall; index 6;
Code: Select all
result.b = 0
port.w = $70
If OpenLibrary(0, "sadirectport\DLL\DirectPort32.dll")
; This line crashes the program... I've tried different combinations of pointers
; and variables, but nothing works.
CallFunction(0, "ReadPortByte",port,@result)
CallFunction(0, "DoneDLL")
Debug result
CloseLibrary(0)
EndIf
-
- User
- Posts: 48
- Joined: Tue Oct 07, 2003 3:10 pm
Paulr,
I use Win98 so I have no problem with I/O.
I haven't used the following but I'm told it does what you want:
http://www.logix4u.net/inpout32.htm
hmmm, it looks like the site has just closed!
Search for inpout32 with Google, I'm sure you'll find a download site. If not, I do have a copy here I could e-mail to you.
The link you posted appears to point to the same type of thing. I'm sure they'll do what you want but I'll have to leave it up to the others in this forum to help you call it from PB, I've no experience of calling DLLs
I use Win98 so I have no problem with I/O.
I haven't used the following but I'm told it does what you want:
http://www.logix4u.net/inpout32.htm
hmmm, it looks like the site has just closed!
Search for inpout32 with Google, I'm sure you'll find a download site. If not, I do have a copy here I could e-mail to you.
The link you posted appears to point to the same type of thing. I'm sure they'll do what you want but I'll have to leave it up to the others in this forum to help you call it from PB, I've no experience of calling DLLs
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
I'm having trouble getting WinIO to work. Can anyone spot the bug?
Paul
ps Dreglor - yes, I'll be careful... I'm assuming I'll be safe if I only use ports $70 and $71, like Roadrunner said? Rewriting my bios is the last thing I want to do.
InitializeWinIo and GetPortVal return nonzero values, but result is always 0, or whatever it's initialised as.result.l = 0
port.w = $70
If OpenLibrary(0, "WinIo.dll")
CallFunction(0, "InitializeWinIo")
CallFunction(0, "GetPortVal", port, @result, 1)
Debug result
CallFunction(0, "ShutdownWinIo")
CloseLibrary(0)
Else
Debug "Not found"
EndIf
Paul
ps Dreglor - yes, I'll be careful... I'm assuming I'll be safe if I only use ports $70 and $71, like Roadrunner said? Rewriting my bios is the last thing I want to do.
-
- User
- Posts: 48
- Joined: Tue Oct 07, 2003 3:10 pm
Paulr,
not true. The time rolls over very slowly, i.e.there is a significant delay from the seconds counting 59->0 and the minutes then incrementing, because the CMOS uses low powewr ripple counters.
Stopping interrupts wouldn't help as it's an internal operation in the CMOS chip and not dependant on CPU activity.
To overcome this, the CMOS has an "update" bit which you check to see if the clock is in the process of being updated.
For setting/reading the alarm time there is no such restriction.
not true. The time rolls over very slowly, i.e.there is a significant delay from the seconds counting 59->0 and the minutes then incrementing, because the CMOS uses low powewr ripple counters.
Stopping interrupts wouldn't help as it's an internal operation in the CMOS chip and not dependant on CPU activity.
To overcome this, the CMOS has an "update" bit which you check to see if the clock is in the process of being updated.
For setting/reading the alarm time there is no such restriction.
Here's the article I read it from:
http://www.programmersheaven.com/2/Art_C_1
http://www.programmersheaven.com/2/Art_C_1
To access CMOS RAM, the index address (0 to 7F H) is output to port 70H, and the data is then read or written at port 71 H. Interrupts should be inhibited while the entire port 70 H /71 H sequence is completed. Alternatively, the port sequence can occur during an interrupt service routine before re-enabling interrupts. If these precautions are not observed, an interrupt service routine could potentially intervene between the output to port 70 H and the subsequent I/O to port 71 H, overwriting the port 70 H value.