Page 1 of 1
Reading / writing cmos bios settings
Posted: Tue Jan 27, 2004 9:06 pm
by paulr
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
Posted: Wed Jan 28, 2004 1:56 am
by Road Runner
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..
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.
Use similar operations to set the alarm time:
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)
You may also need to set/clear Register 12 bit 5 to control if the alarm causes an IRQ or not.
Posted: Wed Jan 28, 2004 1:17 pm
by paulr
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:
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;
And here's my program:
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
Posted: Wed Jan 28, 2004 1:46 pm
by Kale
This might help, especially the device driver used:
viewtopic.php?t=2549
Posted: Wed Jan 28, 2004 2:11 pm
by Road Runner
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
Posted: Wed Jan 28, 2004 2:50 pm
by Psychophanta
I have used "WinIO.dll" for accessing harware ports and I/O addresses with PB, without problems under Windows NT SP4 and Windows 2000.
Posted: Wed Jan 28, 2004 3:39 pm
by Kale
I use 'WinIO.dll' under WinXP Home with no problems

Posted: Wed Jan 28, 2004 8:26 pm
by Dreglor
i just want to leave a note here writeing to teh bois could kill your motherboard very easly so be sure that your program does what it supose to do
Posted: Wed Jan 28, 2004 8:43 pm
by Psychophanta
Yes, very nice point.
Dreglor is right.
It is very important to watch carefully the source code to ensure the ports and/or addresses and values are correctly written before to run the code.
Posted: Wed Jan 28, 2004 9:57 pm
by paulr
I'm having trouble getting WinIO to work. Can anyone spot the bug?
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
InitializeWinIo and GetPortVal return nonzero values, but result is always 0, or whatever it's initialised as.
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.
Posted: Thu Jan 29, 2004 12:51 am
by Dreglor
heh, well not every bois is the same you might want to look up some doucments on your motherboard bois
Posted: Thu Jan 29, 2004 10:10 am
by Rings
copy the sys/vxd driver of WinIO in the same directory as the DLL.
Posted: Thu Jan 29, 2004 8:01 pm
by paulr
Think I'm getting somewhere, I've managed to read the contents of my CMOS and locate where the wakeup time is stored.
I read somewhere that it's advisable to disable interrupts while reading the CMOS as an interrupt at just the wrong time can disrupt the process. Is this possible in PB?
Paul
Posted: Thu Jan 29, 2004 8:10 pm
by Road Runner
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.
Posted: Sat Jan 31, 2004 11:38 am
by paulr
Here's the article I read it from:
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.